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