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 "tcuTextureUtil.hpp"
31 #include "tcuAstcUtil.hpp"
32 #include "deRandom.hpp"
33
34 namespace vkt
35 {
36 namespace pipeline
37 {
38
39 using namespace vk;
40
41 /*! Gets the next multiple of a given divisor */
getNextMultiple(deUint32 divisor,deUint32 value)42 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
43 {
44 if (value % divisor == 0)
45 {
46 return value;
47 }
48 return value + divisor - (value % divisor);
49 }
50
51 /*! Gets the next value that is multiple of all given divisors */
getNextMultiple(const std::vector<deUint32> & divisors,deUint32 value)52 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
53 {
54 deUint32 nextMultiple = value;
55 bool nextMultipleFound = false;
56
57 while (true)
58 {
59 nextMultipleFound = true;
60
61 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
62 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
63
64 if (nextMultipleFound)
65 break;
66
67 DE_ASSERT(nextMultiple < ~((deUint32)0u));
68 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
69 }
70
71 return nextMultiple;
72 }
73
isSupportedSamplableFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)74 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
75 {
76 if (isCompressedFormat(format))
77 {
78 VkPhysicalDeviceFeatures physicalFeatures;
79 const tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(format);
80
81 instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures);
82
83 if (tcu::isAstcFormat(compressedFormat))
84 {
85 if (!physicalFeatures.textureCompressionASTC_LDR)
86 return false;
87 }
88 else if (tcu::isEtcFormat(compressedFormat))
89 {
90 if (!physicalFeatures.textureCompressionETC2)
91 return false;
92 }
93 else
94 {
95 DE_FATAL("Unsupported compressed format");
96 }
97 }
98
99 VkFormatProperties formatProps;
100 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
101
102 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
103 }
104
105 // \todo [2016-01-21 pyry] Update this to just rely on vkDefs.hpp once
106 // CTS has been updated to 1.0.2.
107 enum
108 {
109 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000,
110 };
111
isLinearFilteringSupported(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkFormat format,VkImageTiling tiling)112 bool isLinearFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling)
113 {
114 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
115 const VkFormatFeatureFlags formatFeatures = tiling == VK_IMAGE_TILING_LINEAR
116 ? formatProperties.linearTilingFeatures
117 : formatProperties.optimalTilingFeatures;
118
119 switch (format)
120 {
121 case VK_FORMAT_R32_SFLOAT:
122 case VK_FORMAT_R32G32_SFLOAT:
123 case VK_FORMAT_R32G32B32_SFLOAT:
124 case VK_FORMAT_R32G32B32A32_SFLOAT:
125 case VK_FORMAT_R64_SFLOAT:
126 case VK_FORMAT_R64G64_SFLOAT:
127 case VK_FORMAT_R64G64B64_SFLOAT:
128 case VK_FORMAT_R64G64B64A64_SFLOAT:
129 return (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) != 0;
130
131 default:
132 // \todo [2016-01-21 pyry] Check for all formats once drivers have been updated to 1.0.2
133 // and we have tests to verify format properties.
134 return true;
135 }
136 }
137
getFormatBorderColor(BorderColor color,VkFormat format)138 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format)
139 {
140 if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
141 {
142 switch (color)
143 {
144 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
145 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
146 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
147 default:
148 break;
149 }
150 }
151 else
152 {
153 switch (color)
154 {
155 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
156 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
157 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
158 default:
159 break;
160 }
161 }
162
163 DE_ASSERT(false);
164 return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
165 }
166
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)167 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface& vk,
168 vk::VkDevice device,
169 vk::VkQueue queue,
170 deUint32 queueFamilyIndex,
171 vk::Allocator& allocator,
172 vk::VkImage image,
173 vk::VkFormat format,
174 const tcu::UVec2& renderSize)
175 {
176 Move<VkBuffer> buffer;
177 de::MovePtr<Allocation> bufferAlloc;
178 Move<VkCommandPool> cmdPool;
179 Move<VkCommandBuffer> cmdBuffer;
180 Move<VkFence> fence;
181 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
182 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
183 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
184
185 // Create destination buffer
186 {
187 const VkBufferCreateInfo bufferParams =
188 {
189 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
190 DE_NULL, // const void* pNext;
191 0u, // VkBufferCreateFlags flags;
192 pixelDataSize, // VkDeviceSize size;
193 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
194 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
195 0u, // deUint32 queueFamilyIndexCount;
196 DE_NULL // const deUint32* pQueueFamilyIndices;
197 };
198
199 buffer = createBuffer(vk, device, &bufferParams);
200 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
201 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
202 }
203
204 // Create command pool and buffer
205 {
206 const VkCommandPoolCreateInfo cmdPoolParams =
207 {
208 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
209 DE_NULL, // const void* pNext;
210 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
211 queueFamilyIndex, // deUint32 queueFamilyIndex;
212 };
213
214 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
215
216 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
217 {
218 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
219 DE_NULL, // const void* pNext;
220 *cmdPool, // VkCommandPool commandPool;
221 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
222 1u // deUint32 bufferCount;
223 };
224
225 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
226 }
227
228 // Create fence
229 {
230 const VkFenceCreateInfo fenceParams =
231 {
232 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
233 DE_NULL, // const void* pNext;
234 0u // VkFenceCreateFlags flags;
235 };
236
237 fence = createFence(vk, device, &fenceParams);
238 }
239
240 // Barriers for copying image to buffer
241
242 const VkImageMemoryBarrier imageBarrier =
243 {
244 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
245 DE_NULL, // const void* pNext;
246 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
247 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
248 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
249 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
250 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
251 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
252 image, // VkImage image;
253 { // VkImageSubresourceRange subresourceRange;
254 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
255 0u, // deUint32 baseMipLevel;
256 1u, // deUint32 mipLevels;
257 0u, // deUint32 baseArraySlice;
258 1u // deUint32 arraySize;
259 }
260 };
261
262 const VkBufferMemoryBarrier bufferBarrier =
263 {
264 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
265 DE_NULL, // const void* pNext;
266 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
267 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
268 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
269 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
270 *buffer, // VkBuffer buffer;
271 0u, // VkDeviceSize offset;
272 pixelDataSize // VkDeviceSize size;
273 };
274
275 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
276 {
277 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
278 DE_NULL, // const void* pNext;
279 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
280 (const VkCommandBufferInheritanceInfo*)DE_NULL,
281 };
282
283 // Copy image to buffer
284
285 const VkBufferImageCopy copyRegion =
286 {
287 0u, // VkDeviceSize bufferOffset;
288 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
289 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
290 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceLayers imageSubresource;
291 { 0, 0, 0 }, // VkOffset3D imageOffset;
292 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
293 };
294
295 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
296 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
297 vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
298 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
299 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
300
301 const VkSubmitInfo submitInfo =
302 {
303 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
304 DE_NULL, // const void* pNext;
305 0u, // deUint32 waitSemaphoreCount;
306 DE_NULL, // const VkSemaphore* pWaitSemaphores;
307 DE_NULL,
308 1u, // deUint32 commandBufferCount;
309 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
310 0u, // deUint32 signalSemaphoreCount;
311 DE_NULL // const VkSemaphore* pSignalSemaphores;
312 };
313
314 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
315 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
316
317 // Read buffer data
318 invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
319 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
320
321 return resultLevel;
322 }
323
uploadTestTexture(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,const TestTexture & srcTexture,VkImage destImage)324 void uploadTestTexture (const DeviceInterface& vk,
325 VkDevice device,
326 VkQueue queue,
327 deUint32 queueFamilyIndex,
328 Allocator& allocator,
329 const TestTexture& srcTexture,
330 VkImage destImage)
331 {
332 deUint32 bufferSize;
333 Move<VkBuffer> buffer;
334 de::MovePtr<Allocation> bufferAlloc;
335 Move<VkCommandPool> cmdPool;
336 Move<VkCommandBuffer> cmdBuffer;
337 Move<VkFence> fence;
338 std::vector<deUint32> levelDataSizes;
339
340 // Calculate buffer size
341 bufferSize = (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
342
343 // Create source buffer
344 {
345 const VkBufferCreateInfo bufferParams =
346 {
347 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
348 DE_NULL, // const void* pNext;
349 0u, // VkBufferCreateFlags flags;
350 bufferSize, // VkDeviceSize size;
351 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
352 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
353 0u, // deUint32 queueFamilyIndexCount;
354 DE_NULL, // const deUint32* pQueueFamilyIndices;
355 };
356
357 buffer = createBuffer(vk, device, &bufferParams);
358 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
359 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
360 }
361
362 // Create command pool and buffer
363 {
364 const VkCommandPoolCreateInfo cmdPoolParams =
365 {
366 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
367 DE_NULL, // const void* pNext;
368 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
369 queueFamilyIndex, // deUint32 queueFamilyIndex;
370 };
371
372 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
373
374 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
375 {
376 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
377 DE_NULL, // const void* pNext;
378 *cmdPool, // VkCommandPool commandPool;
379 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
380 1u, // deUint32 bufferCount;
381 };
382
383 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
384 }
385
386 // Create fence
387 {
388 const VkFenceCreateInfo fenceParams =
389 {
390 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
391 DE_NULL, // const void* pNext;
392 0u // VkFenceCreateFlags flags;
393 };
394
395 fence = createFence(vk, device, &fenceParams);
396 }
397
398 // Barriers for copying buffer to image
399 const VkBufferMemoryBarrier preBufferBarrier =
400 {
401 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
402 DE_NULL, // const void* pNext;
403 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
404 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
405 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
406 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
407 *buffer, // VkBuffer buffer;
408 0u, // VkDeviceSize offset;
409 bufferSize // VkDeviceSize size;
410 };
411
412 const VkImageMemoryBarrier preImageBarrier =
413 {
414 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
415 DE_NULL, // const void* pNext;
416 0u, // VkAccessFlags srcAccessMask;
417 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
418 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
419 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
420 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
421 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
422 destImage, // VkImage image;
423 { // VkImageSubresourceRange subresourceRange;
424 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
425 0u, // deUint32 baseMipLevel;
426 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
427 0u, // deUint32 baseArraySlice;
428 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
429 }
430 };
431
432 const VkImageMemoryBarrier postImageBarrier =
433 {
434 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
435 DE_NULL, // const void* pNext;
436 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
437 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
438 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
439 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
440 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
441 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
442 destImage, // VkImage image;
443 { // VkImageSubresourceRange subresourceRange;
444 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
445 0u, // deUint32 baseMipLevel;
446 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
447 0u, // deUint32 baseArraySlice;
448 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
449 }
450 };
451
452 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
453 {
454 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
455 DE_NULL, // const void* pNext;
456 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
457 (const VkCommandBufferInheritanceInfo*)DE_NULL,
458 };
459
460 const std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions();
461
462 // Write buffer data
463 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
464 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
465
466 // Copy buffer to image
467 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
468 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
469 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
470 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
471
472 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
473
474 const VkSubmitInfo submitInfo =
475 {
476 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
477 DE_NULL, // const void* pNext;
478 0u, // deUint32 waitSemaphoreCount;
479 DE_NULL, // const VkSemaphore* pWaitSemaphores;
480 DE_NULL,
481 1u, // deUint32 commandBufferCount;
482 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
483 0u, // deUint32 signalSemaphoreCount;
484 DE_NULL // const VkSemaphore* pSignalSemaphores;
485 };
486
487 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
488 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
489 }
490
491
492 // Utilities for test textures
493
494 template<typename TcuTextureType>
allocateLevels(TcuTextureType & texture)495 void allocateLevels (TcuTextureType& texture)
496 {
497 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
498 texture.allocLevel(levelNdx);
499 }
500
501 template<typename TcuTextureType>
getLevelsVector(const TcuTextureType & texture)502 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
503 {
504 std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
505
506 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
507 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
508
509 return levels;
510 }
511
512
513 // TestTexture
514
TestTexture(const tcu::TextureFormat & format,int width,int height,int depth)515 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
516 {
517 DE_ASSERT(width >= 1);
518 DE_ASSERT(height >= 1);
519 DE_ASSERT(depth >= 1);
520
521 DE_UNREF(format);
522 DE_UNREF(width);
523 DE_UNREF(height);
524 DE_UNREF(depth);
525 }
526
TestTexture(const tcu::CompressedTexFormat & format,int width,int height,int depth)527 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
528 {
529 DE_ASSERT(width >= 1);
530 DE_ASSERT(height >= 1);
531 DE_ASSERT(depth >= 1);
532
533 DE_UNREF(format);
534 DE_UNREF(width);
535 DE_UNREF(height);
536 DE_UNREF(depth);
537 }
538
~TestTexture(void)539 TestTexture::~TestTexture (void)
540 {
541 for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
542 delete m_compressedLevels[levelNdx];
543 }
544
getSize(void) const545 deUint32 TestTexture::getSize (void) const
546 {
547 std::vector<deUint32> offsetMultiples;
548 deUint32 textureSize = 0;
549
550 offsetMultiples.push_back(4);
551 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
552
553 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
554 {
555 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
556 {
557 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
558 textureSize = getNextMultiple(offsetMultiples, textureSize);
559 textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
560 }
561 }
562
563 return textureSize;
564 }
565
getCompressedSize(void) const566 deUint32 TestTexture::getCompressedSize (void) const
567 {
568 if (!isCompressed())
569 throw tcu::InternalError("Texture is not compressed");
570
571 std::vector<deUint32> offsetMultiples;
572 deUint32 textureSize = 0;
573
574 offsetMultiples.push_back(4);
575 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
576
577 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
578 {
579 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
580 {
581 textureSize = getNextMultiple(offsetMultiples, textureSize);
582 textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
583 }
584 }
585
586 return textureSize;
587 }
588
getCompressedLevel(int level,int layer)589 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
590 {
591 DE_ASSERT(level >= 0 && level < getNumLevels());
592 DE_ASSERT(layer >= 0 && layer < getArraySize());
593
594 return *m_compressedLevels[level * getArraySize() + layer];
595 }
596
getCompressedLevel(int level,int layer) const597 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
598 {
599 DE_ASSERT(level >= 0 && level < getNumLevels());
600 DE_ASSERT(layer >= 0 && layer < getArraySize());
601
602 return *m_compressedLevels[level * getArraySize() + layer];
603 }
604
getBufferCopyRegions(void) const605 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
606 {
607 std::vector<deUint32> offsetMultiples;
608 std::vector<VkBufferImageCopy> regions;
609 deUint32 layerDataOffset = 0;
610
611 offsetMultiples.push_back(4);
612
613 if (isCompressed())
614 {
615 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
616
617 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
618 {
619 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
620 {
621 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
622 tcu::IVec3 blockPixelSize = getBlockPixelSize(level.getFormat());
623 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
624
625 const VkBufferImageCopy layerRegion =
626 {
627 layerDataOffset, // VkDeviceSize bufferOffset;
628 (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()), // deUint32 bufferRowLength;
629 (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()), // deUint32 bufferImageHeight;
630 { // VkImageSubresourceLayers imageSubresource;
631 VK_IMAGE_ASPECT_COLOR_BIT,
632 (deUint32)levelNdx,
633 (deUint32)layerNdx,
634 1u
635 },
636 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
637 { // VkExtent3D imageExtent;
638 (deUint32)level.getWidth(),
639 (deUint32)level.getHeight(),
640 (deUint32)level.getDepth()
641 }
642 };
643
644 regions.push_back(layerRegion);
645 layerDataOffset += level.getDataSize();
646 }
647 }
648 }
649 else
650 {
651 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
652
653 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
654 {
655 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
656 {
657 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
658
659 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
660
661 const VkBufferImageCopy layerRegion =
662 {
663 layerDataOffset, // VkDeviceSize bufferOffset;
664 (deUint32)level.getWidth(), // deUint32 bufferRowLength;
665 (deUint32)level.getHeight(), // deUint32 bufferImageHeight;
666 { // VkImageSubresourceLayers imageSubresource;
667 VK_IMAGE_ASPECT_COLOR_BIT,
668 (deUint32)levelNdx,
669 (deUint32)layerNdx,
670 1u
671 },
672 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
673 { // VkExtent3D imageExtent;
674 (deUint32)level.getWidth(),
675 (deUint32)level.getHeight(),
676 (deUint32)level.getDepth()
677 }
678 };
679
680 regions.push_back(layerRegion);
681 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
682 }
683 }
684 }
685
686 return regions;
687 }
688
write(deUint8 * destPtr) const689 void TestTexture::write (deUint8* destPtr) const
690 {
691 std::vector<deUint32> offsetMultiples;
692 deUint32 levelOffset = 0;
693
694 offsetMultiples.push_back(4);
695
696 if (isCompressed())
697 {
698 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
699
700 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
701 {
702 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
703 {
704 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
705
706 const tcu::CompressedTexture& compressedTex = getCompressedLevel(levelNdx, layerNdx);
707
708 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
709 levelOffset += compressedTex.getDataSize();
710 }
711 }
712 }
713 else
714 {
715 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
716
717 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
718 {
719 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
720 {
721 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
722
723 const tcu::ConstPixelBufferAccess srcAccess = getLevel(levelNdx, layerNdx);
724 const tcu::PixelBufferAccess destAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
725
726 tcu::copy(destAccess, srcAccess);
727 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
728 }
729 }
730 }
731 }
732
populateLevels(const std::vector<tcu::PixelBufferAccess> & levels)733 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
734 {
735 for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
736 TestTexture::fillWithGradient(levels[levelNdx]);
737 }
738
populateCompressedLevels(tcu::CompressedTexFormat format,const std::vector<tcu::PixelBufferAccess> & decompressedLevels)739 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
740 {
741 // Generate random compressed data and update decompressed data
742
743 de::Random random(123);
744
745 for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
746 {
747 const tcu::PixelBufferAccess level = decompressedLevels[levelNdx];
748 tcu::CompressedTexture* compressedLevel = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
749 deUint8* const compressedData = (deUint8*)compressedLevel->getData();
750
751 if (tcu::isAstcFormat(format))
752 {
753 // \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
754 tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES,
755 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
756 }
757 else
758 {
759 // Generate random compressed data
760 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
761 compressedData[byteNdx] = 0xFF & random.getUint32();
762 }
763
764 m_compressedLevels.push_back(compressedLevel);
765
766 // Store decompressed data
767 compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
768 }
769 }
770
fillWithGradient(const tcu::PixelBufferAccess & levelAccess)771 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
772 {
773 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
774 tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
775 }
776
777 // TestTexture1D
778
TestTexture1D(const tcu::TextureFormat & format,int width)779 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
780 : TestTexture (format, width, 1, 1)
781 , m_texture (format, width)
782 {
783 allocateLevels(m_texture);
784 TestTexture::populateLevels(getLevelsVector(m_texture));
785 }
786
TestTexture1D(const tcu::CompressedTexFormat & format,int width)787 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
788 : TestTexture (format, width, 1, 1)
789 , m_texture (tcu::getUncompressedFormat(format), width)
790 {
791 allocateLevels(m_texture);
792 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
793 }
794
~TestTexture1D(void)795 TestTexture1D::~TestTexture1D (void)
796 {
797 }
798
getNumLevels(void) const799 int TestTexture1D::getNumLevels (void) const
800 {
801 return m_texture.getNumLevels();
802 }
803
getLevel(int level,int layer)804 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
805 {
806 DE_ASSERT(layer == 0);
807 DE_UNREF(layer);
808 return m_texture.getLevel(level);
809 }
810
getLevel(int level,int layer) const811 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
812 {
813 DE_ASSERT(layer == 0);
814 DE_UNREF(layer);
815 return m_texture.getLevel(level);
816 }
817
getTexture(void) const818 const tcu::Texture1D& TestTexture1D::getTexture (void) const
819 {
820 return m_texture;
821 }
822
823
824 // TestTexture1DArray
825
TestTexture1DArray(const tcu::TextureFormat & format,int width,int arraySize)826 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
827 : TestTexture (format, width, 1, arraySize)
828 , m_texture (format, width, arraySize)
829 {
830 allocateLevels(m_texture);
831 TestTexture::populateLevels(getLevelsVector(m_texture));
832 }
833
TestTexture1DArray(const tcu::CompressedTexFormat & format,int width,int arraySize)834 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
835 : TestTexture (format, width, 1, arraySize)
836 , m_texture (tcu::getUncompressedFormat(format), width, arraySize)
837 {
838 allocateLevels(m_texture);
839
840 std::vector<tcu::PixelBufferAccess> layers;
841 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
842 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
843 layers.push_back(getLevel(levelNdx, layerNdx));
844
845 TestTexture::populateCompressedLevels(format, layers);
846 }
847
~TestTexture1DArray(void)848 TestTexture1DArray::~TestTexture1DArray (void)
849 {
850 }
851
getNumLevels(void) const852 int TestTexture1DArray::getNumLevels (void) const
853 {
854 return m_texture.getNumLevels();
855 }
856
getLevel(int level,int layer)857 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
858 {
859 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
860 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
861 const deUint32 layerOffset = layerSize * layer;
862
863 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
864 }
865
getLevel(int level,int layer) const866 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
867 {
868 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
869 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
870 const deUint32 layerOffset = layerSize * layer;
871
872 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
873 }
874
getTexture(void) const875 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
876 {
877 return m_texture;
878 }
879
getArraySize(void) const880 int TestTexture1DArray::getArraySize (void) const
881 {
882 return m_texture.getNumLayers();
883 }
884
885
886 // TestTexture2D
887
TestTexture2D(const tcu::TextureFormat & format,int width,int height)888 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
889 : TestTexture (format, width, height, 1)
890 , m_texture (format, width, height)
891 {
892 allocateLevels(m_texture);
893 TestTexture::populateLevels(getLevelsVector(m_texture));
894 }
895
TestTexture2D(const tcu::CompressedTexFormat & format,int width,int height)896 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
897 : TestTexture (format, width, height, 1)
898 , m_texture (tcu::getUncompressedFormat(format), width, height)
899 {
900 allocateLevels(m_texture);
901 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
902 }
903
~TestTexture2D(void)904 TestTexture2D::~TestTexture2D (void)
905 {
906 }
907
getNumLevels(void) const908 int TestTexture2D::getNumLevels (void) const
909 {
910 return m_texture.getNumLevels();
911 }
912
getLevel(int level,int layer)913 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
914 {
915 DE_ASSERT(layer == 0);
916 DE_UNREF(layer);
917 return m_texture.getLevel(level);
918 }
919
getLevel(int level,int layer) const920 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
921 {
922 DE_ASSERT(layer == 0);
923 DE_UNREF(layer);
924 return m_texture.getLevel(level);
925 }
926
getTexture(void) const927 const tcu::Texture2D& TestTexture2D::getTexture (void) const
928 {
929 return m_texture;
930 }
931
932
933 // TestTexture2DArray
934
TestTexture2DArray(const tcu::TextureFormat & format,int width,int height,int arraySize)935 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
936 : TestTexture (format, width, height, arraySize)
937 , m_texture (format, width, height, arraySize)
938 {
939 allocateLevels(m_texture);
940 TestTexture::populateLevels(getLevelsVector(m_texture));
941 }
942
TestTexture2DArray(const tcu::CompressedTexFormat & format,int width,int height,int arraySize)943 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
944 : TestTexture (format, width, height, arraySize)
945 , m_texture (tcu::getUncompressedFormat(format), width, height, arraySize)
946 {
947 allocateLevels(m_texture);
948
949 std::vector<tcu::PixelBufferAccess> layers;
950 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
951 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
952 layers.push_back(getLevel(levelNdx, layerNdx));
953
954 TestTexture::populateCompressedLevels(format, layers);
955 }
956
~TestTexture2DArray(void)957 TestTexture2DArray::~TestTexture2DArray (void)
958 {
959 }
960
getNumLevels(void) const961 int TestTexture2DArray::getNumLevels (void) const
962 {
963 return m_texture.getNumLevels();
964 }
965
getLevel(int level,int layer)966 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
967 {
968 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
969 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
970 const deUint32 layerOffset = layerSize * layer;
971
972 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
973 }
974
getLevel(int level,int layer) const975 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
976 {
977 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
978 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
979 const deUint32 layerOffset = layerSize * layer;
980
981 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
982 }
983
getTexture(void) const984 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
985 {
986 return m_texture;
987 }
988
getArraySize(void) const989 int TestTexture2DArray::getArraySize (void) const
990 {
991 return m_texture.getNumLayers();
992 }
993
994
995 // TestTexture3D
996
TestTexture3D(const tcu::TextureFormat & format,int width,int height,int depth)997 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
998 : TestTexture (format, width, height, depth)
999 , m_texture (format, width, height, depth)
1000 {
1001 allocateLevels(m_texture);
1002 TestTexture::populateLevels(getLevelsVector(m_texture));
1003 }
1004
TestTexture3D(const tcu::CompressedTexFormat & format,int width,int height,int depth)1005 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
1006 : TestTexture (format, width, height, depth)
1007 , m_texture (tcu::getUncompressedFormat(format), width, height, depth)
1008 {
1009 allocateLevels(m_texture);
1010 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1011 }
1012
~TestTexture3D(void)1013 TestTexture3D::~TestTexture3D (void)
1014 {
1015 }
1016
getNumLevels(void) const1017 int TestTexture3D::getNumLevels (void) const
1018 {
1019 return m_texture.getNumLevels();
1020 }
1021
getLevel(int level,int layer)1022 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
1023 {
1024 DE_ASSERT(layer == 0);
1025 DE_UNREF(layer);
1026 return m_texture.getLevel(level);
1027 }
1028
getLevel(int level,int layer) const1029 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
1030 {
1031 DE_ASSERT(layer == 0);
1032 DE_UNREF(layer);
1033 return m_texture.getLevel(level);
1034 }
1035
getTexture(void) const1036 const tcu::Texture3D& TestTexture3D::getTexture (void) const
1037 {
1038 return m_texture;
1039 }
1040
1041
1042 // TestTextureCube
1043
1044 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1045 {
1046 tcu::CUBEFACE_POSITIVE_X,
1047 tcu::CUBEFACE_NEGATIVE_X,
1048 tcu::CUBEFACE_POSITIVE_Y,
1049 tcu::CUBEFACE_NEGATIVE_Y,
1050 tcu::CUBEFACE_POSITIVE_Z,
1051 tcu::CUBEFACE_NEGATIVE_Z
1052 };
1053
TestTextureCube(const tcu::TextureFormat & format,int size)1054 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1055 : TestTexture (format, size, size, 1)
1056 , m_texture (format, size)
1057 {
1058 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1059 {
1060 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1061 {
1062 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1063 TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1064 }
1065 }
1066 }
1067
TestTextureCube(const tcu::CompressedTexFormat & format,int size)1068 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1069 : TestTexture (format, size, size, 1)
1070 , m_texture (tcu::getUncompressedFormat(format), size)
1071 {
1072 std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1073
1074 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1075 {
1076 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1077 {
1078 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1079 levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1080 }
1081 }
1082
1083 TestTexture::populateCompressedLevels(format, levels);
1084 }
1085
~TestTextureCube(void)1086 TestTextureCube::~TestTextureCube (void)
1087 {
1088 }
1089
getNumLevels(void) const1090 int TestTextureCube::getNumLevels (void) const
1091 {
1092 return m_texture.getNumLevels();
1093 }
1094
getLevel(int level,int face)1095 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int face)
1096 {
1097 return m_texture.getLevelFace(level, (tcu::CubeFace)face);
1098 }
1099
getLevel(int level,int face) const1100 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int face) const
1101 {
1102 return m_texture.getLevelFace(level, (tcu::CubeFace)face);
1103 }
1104
getArraySize(void) const1105 int TestTextureCube::getArraySize (void) const
1106 {
1107 return (int)tcu::CUBEFACE_LAST;
1108 }
1109
getTexture(void) const1110 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1111 {
1112 return m_texture;
1113 }
1114
1115 // TestTextureCubeArray
1116
TestTextureCubeArray(const tcu::TextureFormat & format,int size,int arraySize)1117 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1118 : TestTexture (format, size, size, arraySize)
1119 , m_texture (format, size, arraySize)
1120 {
1121 allocateLevels(m_texture);
1122 TestTexture::populateLevels(getLevelsVector(m_texture));
1123 }
1124
TestTextureCubeArray(const tcu::CompressedTexFormat & format,int size,int arraySize)1125 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1126 : TestTexture (format, size, size, arraySize)
1127 , m_texture (tcu::getUncompressedFormat(format), size, arraySize)
1128 {
1129 DE_ASSERT(arraySize % 6 == 0);
1130
1131 allocateLevels(m_texture);
1132
1133 std::vector<tcu::PixelBufferAccess> layers;
1134 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1135 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1136 layers.push_back(getLevel(levelNdx, layerNdx));
1137
1138 TestTexture::populateCompressedLevels(format, layers);
1139 }
1140
~TestTextureCubeArray(void)1141 TestTextureCubeArray::~TestTextureCubeArray (void)
1142 {
1143 }
1144
getNumLevels(void) const1145 int TestTextureCubeArray::getNumLevels (void) const
1146 {
1147 return m_texture.getNumLevels();
1148 }
1149
getLevel(int level,int layer)1150 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1151 {
1152 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1153 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1154 const deUint32 layerOffset = layerSize * layer;
1155
1156 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1157 }
1158
getLevel(int level,int layer) const1159 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1160 {
1161 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1162 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1163 const deUint32 layerOffset = layerSize * layer;
1164
1165 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1166 }
1167
getArraySize(void) const1168 int TestTextureCubeArray::getArraySize (void) const
1169 {
1170 return m_texture.getDepth();
1171 }
1172
getTexture(void) const1173 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
1174 {
1175 return m_texture;
1176 }
1177
1178 } // pipeline
1179 } // vkt
1180