1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2021 Google LLC.
6 *
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 Tests that images using a block-compressed format are sampled
23 * correctly
24 *
25 * These tests create a storage image using a 128-bit or a 64-bit
26 * block-compressed image format and an ImageView using an uncompressed
27 * format. Each test case then fills the storage image with compressed
28 * color values in a compute shader and samples the storage image. If the
29 * sampled values are pure blue, the test passes.
30 *//*--------------------------------------------------------------------*/
31
32 #include "deUniquePtr.hpp"
33 #include "deStringUtil.hpp"
34
35 #include "tcuVectorType.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuImageCompare.hpp"
38 #include "tcuTexture.hpp"
39
40 #include "vkDefs.hpp"
41 #include "vkRef.hpp"
42 #include "vkRefUtil.hpp"
43 #include "vkPrograms.hpp"
44 #include "vkMemUtil.hpp"
45 #include "vkBuilderUtil.hpp"
46 #include "vkImageUtil.hpp"
47 #include "vkCmdUtil.hpp"
48 #include "vkObjUtil.hpp"
49 #include "vkTypeUtil.hpp"
50 #include "vkImageWithMemory.hpp"
51 #include "vktImageTestsUtil.hpp"
52 #include "vkBarrierUtil.hpp"
53
54 #include "vktTestCaseUtil.hpp"
55 #include "tcuTestLog.hpp"
56
57 #include <string>
58
59 using namespace vk;
60
61 namespace vkt
62 {
63 namespace image
64 {
65 namespace
66 {
67 using tcu::IVec3;
68 using tcu::Vec2;
69 using tcu::Vec4;
70 using std::vector;
71 using de::MovePtr;
72 using tcu::TextureLevel;
73 using tcu::PixelBufferAccess;
74 using tcu::ConstPixelBufferAccess;
75
76 const VkDeviceSize BUFFERSIZE = 100u * 1024;
77 const int WIDTH = 80;
78 const int HEIGHT = 80;
79 const int FACES = 6;
80
makeImageCreateInfo(const IVec3 & size,const VkFormat & format,bool storageImage,bool cubemap)81 inline VkImageCreateInfo makeImageCreateInfo (const IVec3& size, const VkFormat& format, bool storageImage, bool cubemap)
82 {
83 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
84 | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
85 VkImageCreateFlags createFlags = cubemap ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : DE_NULL;
86 const deUint32 layerCount = cubemap ? 6u : 1u;
87
88 if (storageImage)
89 {
90 usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
91 | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
92 createFlags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT
93 | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT;
94 }
95
96 const VkImageCreateInfo imageParams =
97 {
98 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
99 DE_NULL, // const void* pNext;
100 createFlags, // VkImageCreateFlags flags;
101 VK_IMAGE_TYPE_2D, // VkImageType imageType;
102 format, // VkFormat format;
103 makeExtent3D(size.x(), size.y(), 1u), // VkExtent3D extent;
104 1u, // deUint32 mipLevels;
105 layerCount, // deUint32 arrayLayers;
106 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
107 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
108 usageFlags, // VkImageUsageFlags usage;
109 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
110 0u, // deUint32 queueFamilyIndexCount;
111 DE_NULL, // const deUint32* pQueueFamilyIndices;
112 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
113 };
114
115 return imageParams;
116 }
117
makeVertexBuffer(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)118 Move<VkBuffer> makeVertexBuffer (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
119 {
120 const VkBufferCreateInfo vertexBufferParams =
121 {
122 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
123 DE_NULL, // const void* pNext;
124 0u, // VkBufferCreateFlags flags;
125 BUFFERSIZE, // VkDeviceSize size;
126 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
127 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
128 1u, // deUint32 queueFamilyIndexCount;
129 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
130 };
131
132 Move<VkBuffer> vertexBuffer = createBuffer(vk, device, &vertexBufferParams);
133 return vertexBuffer;
134 }
135
136 class SampleDrawnTextureTestInstance : public TestInstance
137 {
138 public:
139 SampleDrawnTextureTestInstance (Context& context,
140 const VkFormat imageFormat,
141 const VkFormat imageViewFormat,
142 const bool twoSamplers,
143 const bool cubemap);
144
145 tcu::TestStatus iterate (void);
146
147 private:
148 const VkFormat m_imageFormat;
149 const VkFormat m_imageViewFormat;
150 const bool m_twoSamplers;
151 const bool m_cubemap;
152 };
153
SampleDrawnTextureTestInstance(Context & context,const VkFormat imageFormat,const VkFormat imageViewFormat,const bool twoSamplers,const bool cubemap)154 SampleDrawnTextureTestInstance::SampleDrawnTextureTestInstance (Context& context, const VkFormat imageFormat, const VkFormat imageViewFormat,
155 const bool twoSamplers, const bool cubemap)
156 : TestInstance (context)
157 , m_imageFormat (imageFormat)
158 , m_imageViewFormat (imageViewFormat)
159 , m_twoSamplers (twoSamplers)
160 , m_cubemap (cubemap)
161 {
162 }
163
164 template<typename T>
sizeInBytes(const vector<T> & vec)165 inline size_t sizeInBytes (const vector<T>& vec)
166 {
167 return vec.size() * sizeof(vec[0]);
168 }
169
makeSampler(const DeviceInterface & vk,const VkDevice & device)170 Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice& device)
171 {
172 const VkSamplerCreateInfo samplerParams =
173 {
174 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
175 DE_NULL, // const void* pNext;
176 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
177 VK_FILTER_NEAREST, // VkFilter magFilter;
178 VK_FILTER_NEAREST, // VkFilter minFilter;
179 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
180 VK_SAMPLER_ADDRESS_MODE_REPEAT, // VkSamplerAddressMode addressModeU;
181 VK_SAMPLER_ADDRESS_MODE_REPEAT, // VkSamplerAddressMode addressModeV;
182 VK_SAMPLER_ADDRESS_MODE_REPEAT, // VkSamplerAddressMode addressModeW;
183 0.0f, // float mipLodBias;
184 VK_FALSE, // VkBool32 anisotropyEnable;
185 1.0f, // float maxAnisotropy;
186 VK_FALSE, // VkBool32 compareEnable;
187 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
188 0.0f, // float minLod;
189 0.0f, // float maxLod;
190 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
191 VK_FALSE, // VkBool32 unnormalizedCoordinates;
192 };
193
194 return createSampler(vk, device, &samplerParams);
195 }
196
197 struct Vertex
198 {
Vertexvkt::image::__anona8b655430111::Vertex199 Vertex(Vec4 position_, Vec2 uv_) : position(position_), uv(uv_) {}
200 Vec4 position;
201 Vec2 uv;
202
203 static VkVertexInputBindingDescription getBindingDescription (void);
204 static vector<VkVertexInputAttributeDescription> getAttributeDescriptions (void);
205 };
206
getBindingDescription(void)207 VkVertexInputBindingDescription Vertex::getBindingDescription (void)
208 {
209 static const VkVertexInputBindingDescription desc =
210 {
211 0u, // deUint32 binding;
212 static_cast<deUint32>(sizeof(Vertex)), // deUint32 stride;
213 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
214 };
215
216 return desc;
217 }
218
getAttributeDescriptions(void)219 vector<VkVertexInputAttributeDescription> Vertex::getAttributeDescriptions (void)
220 {
221 static const vector<VkVertexInputAttributeDescription> desc =
222 {
223 {
224 0u, // deUint32 location;
225 0u, // deUint32 binding;
226 vk::VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
227 static_cast<deUint32>(offsetof(Vertex, position)), // deUint32 offset;
228 },
229 {
230 1u, // deUint32 location;
231 0u, // deUint32 binding;
232 vk::VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
233 static_cast<deUint32>(offsetof(Vertex, uv)), // deUint32 offset;
234 },
235 };
236
237 return desc;
238 }
239
240 // Generates the vertices of a full quad and texture coordinates of each vertex.
generateVertices(void)241 vector<Vertex> generateVertices (void)
242 {
243 vector<Vertex> vertices;
244 vertices.push_back(Vertex(Vec4(-1.0f, -1.0f, 0.0f, 1.0f), Vec2(0.0f, 0.0f)));
245 vertices.push_back(Vertex(Vec4( 1.0f, -1.0f, 0.0f, 1.0f), Vec2(1.0f, 0.0f)));
246 vertices.push_back(Vertex(Vec4(-1.0f, 1.0f, 0.0f, 1.0f), Vec2(0.0f, 1.0f)));
247 vertices.push_back(Vertex(Vec4( 1.0f, -1.0f, 0.0f, 1.0f), Vec2(1.0f, 0.0f)));
248 vertices.push_back(Vertex(Vec4( 1.0f, 1.0f, 0.0f, 1.0f), Vec2(1.0f, 1.0f)));
249 vertices.push_back(Vertex(Vec4(-1.0f, 1.0f, 0.0f, 1.0f), Vec2(0.0f, 1.0f)));
250
251 return vertices;
252 }
253
254 // Generates a reference image filled with pure blue.
makeReferenceImage(const VkFormat format,int width,int height)255 TextureLevel makeReferenceImage (const VkFormat format, int width, int height)
256 {
257 TextureLevel referenceImage(mapVkFormat(format), width, height, 1);
258 for (int y = 0; y < height; y++)
259 for (int x = 0; x < width; x++)
260 referenceImage.getAccess().setPixel(tcu::IVec4(0, 0, 255, 255), x, y, 0);
261
262 return referenceImage;
263 }
264
iterate(void)265 tcu::TestStatus SampleDrawnTextureTestInstance::iterate (void)
266 {
267 DE_ASSERT(m_imageFormat == VK_FORMAT_BC1_RGB_UNORM_BLOCK || m_imageFormat == VK_FORMAT_BC3_UNORM_BLOCK);
268
269 const DeviceInterface& vk = m_context.getDeviceInterface();
270 const VkDevice device = m_context.getDevice();
271 Allocator& allocator = m_context.getDefaultAllocator();
272 const VkQueue queue = m_context.getUniversalQueue();
273 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
274
275 const IVec3 imageSize = {static_cast<int>(WIDTH), HEIGHT, 1};
276 const VkExtent2D renderSize = {deUint32(WIDTH), deUint32(HEIGHT)};
277 const VkRect2D renderArea = makeRect2D(makeExtent3D(WIDTH, HEIGHT, 1u));
278 const vector<VkRect2D> scissors (1u, renderArea);
279 const vector<VkViewport> viewports (1u, makeViewport(makeExtent3D(WIDTH, HEIGHT, 1u)));
280
281 const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
282 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
283
284 const Unique<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
285 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 6)
286 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 12)
287 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 21u));
288
289 const VkFormat renderedImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
290
291 // Create a storage image. The first pipeline fills it and the second pipeline
292 // uses it as a sampling source.
293 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(imageSize, m_imageFormat, true, m_cubemap);
294 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1, 0, 1);
295 const ImageWithMemory storageImage (vk, device, m_context.getDefaultAllocator(), imageCreateInfo, MemoryRequirement::Any);
296
297 // Create image views and descriptor sets for the first pipeline
298 Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
299 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
300 .build(vk, device);
301
302 Move<VkImageView> storageImageImageView;
303 VkDescriptorImageInfo storageImageDscrInfo;
304 Move<VkDescriptorSet> storageImageDescriptorSet;
305
306 // Cubemap tests use separate image views for each side of a cubemap.
307 vector<VkImageSubresourceRange> cubeSubresourceRanges;
308 vector<Move<VkImageView>> cubeStorageImageViews;
309 vector<VkDescriptorImageInfo> cubeStorageDscrImageInfos;
310 vector<Move<VkDescriptorSet>> cubeStorageDscrSets;
311
312 if (m_cubemap)
313 {
314 DescriptorSetUpdateBuilder updateBuilder;
315 for (int i = 0; i < FACES; i++)
316 {
317 cubeSubresourceRanges.emplace_back(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1, i, 1));
318 cubeStorageImageViews.emplace_back(makeImageView(vk, device, *storageImage, VK_IMAGE_VIEW_TYPE_2D, m_imageViewFormat, cubeSubresourceRanges[i]));
319 cubeStorageDscrImageInfos.emplace_back(makeDescriptorImageInfo(DE_NULL, *cubeStorageImageViews[i], VK_IMAGE_LAYOUT_GENERAL));
320 cubeStorageDscrSets.emplace_back(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
321 updateBuilder.writeSingle(*cubeStorageDscrSets[i], DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &cubeStorageDscrImageInfos[i]);
322 }
323 updateBuilder.update(vk, device);
324 }
325 else
326 {
327 storageImageImageView = makeImageView(vk, device, *storageImage, VK_IMAGE_VIEW_TYPE_2D, m_imageViewFormat, imageSubresourceRange);
328 storageImageDscrInfo = makeDescriptorImageInfo(DE_NULL, *storageImageImageView, VK_IMAGE_LAYOUT_GENERAL);
329 storageImageDescriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
330
331 DescriptorSetUpdateBuilder()
332 .writeSingle(*storageImageDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &storageImageDscrInfo)
333 .update(vk, device);
334 }
335
336 // Create a compute pipeline.
337 Move<VkShaderModule> computeShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0u);
338 const VkPushConstantRange pushConstantRange =
339 {
340 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
341 0u, // uint32_t offset;
342 (deUint32)sizeof(deUint32), // uint32_t size;
343 };
344
345 const Move<VkPipelineLayout> computePipelineLayout = makePipelineLayout(vk, device, 1, &(*descriptorSetLayout), 1, &pushConstantRange);
346 Move<VkPipeline> computePipeline = makeComputePipeline(vk, device, *computePipelineLayout, *computeShader);
347
348
349 // Create a graphics pipeline and all the necessary components for sampling the storage image
350
351 // The first sampler uses an uncompressed format.
352 const Unique<VkSampler> sampler (makeSampler(vk, device));
353
354 // The second sampler uses the same format as the image.
355 const Unique<VkSampler> sampler2 (makeSampler(vk, device));
356
357 // Image views implicitly derive the usage flags from the image. Drop the storage image flag since it's incompatible
358 // with the compressed format and unnecessary in sampling.
359 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
360 VkImageViewUsageCreateInfo imageViewUsageInfo =
361 {
362 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, //VkStructureType sType;
363 DE_NULL, //const void* pNext;
364 usageFlags, //VkImageUsageFlags usage;
365 };
366
367 Move<VkImageView> sampledImageView;
368 Move<VkImageView> sampledImageView2;
369 VkDescriptorImageInfo samplerDscrImageInfo;
370 VkDescriptorImageInfo samplerDscrImageInfo2;
371 Move<VkDescriptorSet> graphicsDescriptorSet;
372
373 // Cubemap tests use separate image views for each side of a cubemap.
374 vector<Move<VkImageView>> cubeSamplerImageViews;
375 vector<Move<VkImageView>> cubeSampler2ImageViews;
376 vector<VkDescriptorImageInfo> cubeSamplerDscrImageInfos;
377 vector<VkDescriptorImageInfo> cubeSampler2DscrImageInfos;
378 vector<Move<VkDescriptorSet>> cubeSamplerDescriptorSets;
379
380 const auto graphicsDscrSetLayout (DescriptorSetLayoutBuilder()
381 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler2.get())
382 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get())
383 .build(vk, device));
384
385 if (m_cubemap)
386 {
387 DescriptorSetUpdateBuilder updateBuilder;
388 for (int i = 0; i < FACES; i++)
389 {
390 cubeSamplerImageViews.emplace_back(makeImageView(vk, device, *storageImage, VK_IMAGE_VIEW_TYPE_2D, m_imageFormat, cubeSubresourceRanges[i], &imageViewUsageInfo));
391 cubeSamplerDscrImageInfos.emplace_back(makeDescriptorImageInfo(sampler2.get(), *cubeSamplerImageViews[i], VK_IMAGE_LAYOUT_GENERAL));
392 cubeSamplerDescriptorSets.emplace_back(makeDescriptorSet(vk, device, *descriptorPool, *graphicsDscrSetLayout));
393 updateBuilder.writeSingle(*cubeSamplerDescriptorSets[i], DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &cubeSamplerDscrImageInfos[i]);
394 }
395
396 if (m_twoSamplers)
397 {
398 for (int i = 0; i < FACES; i++)
399 {
400 cubeSampler2ImageViews.emplace_back(makeImageView(vk, device, *storageImage, VK_IMAGE_VIEW_TYPE_2D, m_imageViewFormat, cubeSubresourceRanges[i]));
401 cubeSampler2DscrImageInfos.emplace_back(makeDescriptorImageInfo(sampler.get(), *cubeSampler2ImageViews[i], VK_IMAGE_LAYOUT_GENERAL));
402 updateBuilder.writeSingle(*cubeSamplerDescriptorSets[i], DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &cubeSampler2DscrImageInfos[i]);
403 }
404 }
405 updateBuilder.update(vk, device);
406 }
407 else
408 {
409 const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1, 0, 1);
410 DescriptorSetUpdateBuilder updateBuilder;
411
412 sampledImageView2 = makeImageView(vk, device, *storageImage, VK_IMAGE_VIEW_TYPE_2D, m_imageFormat, subresourceRange, &imageViewUsageInfo);
413 samplerDscrImageInfo2 = makeDescriptorImageInfo(sampler2.get(), *sampledImageView2, VK_IMAGE_LAYOUT_GENERAL);
414 graphicsDescriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *graphicsDscrSetLayout);
415
416 if (m_twoSamplers)
417 {
418 sampledImageView = makeImageView(vk, device, *storageImage, VK_IMAGE_VIEW_TYPE_2D, m_imageViewFormat, subresourceRange);
419 samplerDscrImageInfo = makeDescriptorImageInfo(sampler.get(), *sampledImageView, VK_IMAGE_LAYOUT_GENERAL);
420 }
421
422 updateBuilder.writeSingle(*graphicsDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &samplerDscrImageInfo2);
423 if (m_twoSamplers)
424 updateBuilder.writeSingle(*graphicsDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &samplerDscrImageInfo);
425
426 updateBuilder.update(vk, device);
427 }
428
429 // Sampled values will be rendered on this image.
430 const VkImageSubresourceRange targetSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1, 0, 1);
431 const VkImageCreateInfo targetImageCreateInfo = makeImageCreateInfo(imageSize, renderedImageFormat, false, false);
432
433 const ImageWithMemory targetImage (vk, device, m_context.getDefaultAllocator(), targetImageCreateInfo, MemoryRequirement::Any);
434 Move<VkImageView> targetImageView = makeImageView(vk, device, *targetImage, VK_IMAGE_VIEW_TYPE_2D, renderedImageFormat, targetSubresourceRange);
435
436 // Clear the render target image as black and do a layout transition.
437 clearColorImage(vk, device, m_context.getUniversalQueue(), m_context.getUniversalQueueFamilyIndex(), targetImage.get(),
438 Vec4(0, 0, 0, 0), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
439
440 const VkPushConstantRange pushConstantRange2 =
441 {
442 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
443 0u, // uint32_t offset;
444 (deUint32)sizeof(deUint32), // uint32_t size;
445 };
446
447 const Move<VkPipelineLayout> graphicsPipelineLayout = makePipelineLayout(vk, device, 1, &(*graphicsDscrSetLayout), 1, &pushConstantRange2);
448
449 // Vertices for a full quad and texture coordinates for each vertex.
450 const vector<Vertex> vertices = generateVertices();
451 Move<VkBuffer> vertexBuffer = makeVertexBuffer(vk, device, queueFamilyIndex);
452 de::MovePtr<Allocation> vertexBufferAlloc = bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible);
453 const VkDeviceSize vertexBufferOffset = 0ull;
454 deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], sizeInBytes(vertices));
455 flushAlloc(vk, device, *vertexBufferAlloc);
456
457 const auto vtxBindingDescription = Vertex::getBindingDescription();
458 const auto vtxAttrDescriptions = Vertex::getAttributeDescriptions();
459
460 const VkPipelineVertexInputStateCreateInfo vtxInputInfo =
461 {
462 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
463 nullptr, // const void* pNext
464 0u, // VkPipelineVertexInputStateCreateFlags flags
465 1u, // deUint32 vertexBindingDescriptionCount
466 &vtxBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
467 static_cast<deUint32>(vtxAttrDescriptions.size()), // deUint32 vertexAttributeDescriptionCount
468 vtxAttrDescriptions.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
469 };
470
471 Move<VkShaderModule> vertexShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u);
472 Move<VkShaderModule> fragmentShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u);
473
474 // Create a render pass, a framebuffer, and the second pipeline.
475 Move<VkRenderPass> renderPass = makeRenderPass(vk, device, renderedImageFormat, VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_LOAD,
476 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
477 Move<VkFramebuffer> framebuffer = makeFramebuffer(vk, device, *renderPass, targetImageView.get(), renderSize.width, renderSize.height);
478 const Move<VkPipeline> graphicsPipeline = makeGraphicsPipeline(vk, device, graphicsPipelineLayout.get(), vertexShader.get(), DE_NULL,
479 DE_NULL, DE_NULL, fragmentShader.get(), renderPass.get(), viewports, scissors,
480 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, 0u, &vtxInputInfo);
481
482 // Create a result buffer.
483 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(BUFFERSIZE, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
484 Move<VkBuffer> resultBuffer = createBuffer(vk, device, &resultBufferCreateInfo);
485 MovePtr<Allocation> resultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resultBuffer), MemoryRequirement::HostVisible);
486 TextureLevel resultImage (mapVkFormat(renderedImageFormat), renderSize.width, renderSize.height, 1);
487 VK_CHECK(vk.bindBufferMemory(device, *resultBuffer, resultBufferMemory->getMemory(), resultBufferMemory->getOffset()));
488
489 // Generate a reference image.
490 TextureLevel expectedImage = makeReferenceImage(renderedImageFormat, WIDTH, HEIGHT);
491
492 beginCommandBuffer(vk, *cmdBuffer);
493
494 // Do a layout transition for the storage image.
495 const VkImageSubresourceRange imageSubresourceRange2 = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1, 0, m_cubemap ? 6 : 1);
496 const auto barrier1 = makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
497 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
498 storageImage.get(), imageSubresourceRange2);
499 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1u, &barrier1);
500
501 // Bind the vertices and the descriptors used in the graphics pipeline.
502 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
503
504 // Fill the storage image and sample it twice.
505 for (int pass = 0; pass < 2; pass++)
506 {
507 // If both samplers are enabled, it's not necessary to run the compute shader twice since it already writes
508 // the expected values on the first pass. The first sampler uses an uncompressed image format so the result
509 // image will contain garbage if the second sampler doesn't work properly.
510 if (!m_twoSamplers || pass == 0)
511 {
512 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
513 vk.cmdPushConstants(*cmdBuffer, *computePipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(deInt32), &pass);
514
515 // If cubemaps are enabled, loop over six times and bind the next face of the cubemap image on each iteration.
516 if (m_cubemap)
517 {
518 for (int face = 0; face < FACES; face++)
519 {
520 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipelineLayout, 0u, 1u, &(cubeStorageDscrSets[face].get()), 0u, DE_NULL);
521 vk.cmdDispatch(*cmdBuffer, WIDTH, HEIGHT, 1u);
522 }
523 }
524 else
525 {
526 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipelineLayout, 0u, 1u, &storageImageDescriptorSet.get(), 0u, DE_NULL);
527 vk.cmdDispatch(*cmdBuffer, WIDTH, HEIGHT, 1u);
528 }
529
530 const auto barrier2 = makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
531 VK_IMAGE_LAYOUT_GENERAL, storageImage.get(), imageSubresourceRange);
532 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1u, &barrier2);
533 }
534
535 vk.cmdPushConstants(*cmdBuffer, *graphicsPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &pass);
536
537 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
538
539 // If cubemaps are enabled, loop over six times and bind the next face of the cubemap image on each iteration.
540 if (m_cubemap)
541 {
542 for (int face = 0; face < FACES; face++)
543 {
544 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipelineLayout, 0u, 1u, &(cubeSamplerDescriptorSets[face].get()), 0u, DE_NULL);
545
546 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, imageSize.x(), imageSize.y()),0u, DE_NULL);
547 vk.cmdDraw(*cmdBuffer, 6u, 1u, 0u, 0u);
548 endRenderPass(vk, *cmdBuffer);
549
550 if (face < FACES-1)
551 {
552 const auto barrier4 = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
553 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
554 targetImage.get(), targetSubresourceRange);
555 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
556 0, 0, DE_NULL, 0, DE_NULL, 1u, &barrier4);
557 }
558 }
559 }
560 else
561 {
562 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipelineLayout, 0u, 1u, &(graphicsDescriptorSet.get()), 0u, DE_NULL);
563
564 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, imageSize.x(), imageSize.y()),0u, DE_NULL);
565 vk.cmdDraw(*cmdBuffer, 6u, 1u, 0u, 0u);
566 endRenderPass(vk, *cmdBuffer);
567 }
568
569 if (pass == 0)
570 {
571 const auto barrier3 = makeImageMemoryBarrier(VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL,
572 VK_IMAGE_LAYOUT_GENERAL, storageImage.get(), imageSubresourceRange);
573 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1u, &barrier3);
574
575 const auto barrier4 = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
576 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
577 targetImage.get(), targetSubresourceRange);
578 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1u, &barrier4);
579 }
580 }
581
582 // Copy the sampled values from the target image into the result image.
583 copyImageToBuffer(vk, *cmdBuffer, *targetImage, *resultBuffer, tcu::IVec2(WIDTH, HEIGHT), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
584
585 endCommandBuffer(vk, *cmdBuffer);
586 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
587
588 invalidateAlloc(vk, device, *resultBufferMemory);
589
590 clear(resultImage.getAccess(), tcu::IVec4(0));
591 copy(resultImage.getAccess(), ConstPixelBufferAccess(resultImage.getFormat(), resultImage.getSize(), resultBufferMemory->getHostPtr()));
592
593 bool result = true;
594
595 if (m_cubemap)
596 {
597 // The first pass draws pure red on the faces and the second pass redraws them with pure blue.
598 // Sampling anywhere should produce colors with a 0.0 red component and > 0.0 blue and alpha components.
599 for (deUint32 y = 0; y < renderSize.height; y++)
600 {
601 for (deUint32 x = 0; x < renderSize.width; x++)
602 {
603 const deUint8* ptr = static_cast<const deUint8 *>(resultImage.getAccess().getPixelPtr(x, y, 0));
604 const tcu::IVec4 val = tcu::IVec4(ptr[0], ptr[1], ptr[2], ptr[3]);
605 if (!(val[0] == 0 && val[2] > 0 && val[3] > 0))
606 result = false;
607 }
608 }
609
610 // Log attachment contents.
611 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Attachment ", "")
612 << tcu::TestLog::Image("Rendered image", "Rendered image", resultImage.getAccess())
613 << tcu::TestLog::EndImageSet;
614 }
615 else
616 {
617 // Each test case should render pure blue as the result.
618 result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Image Comparison", "",
619 expectedImage.getAccess(), resultImage.getAccess(),
620 tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
621 }
622
623 if (result)
624 return tcu::TestStatus::pass("pass");
625 else
626 return tcu::TestStatus::fail("fail");
627 }
628
629 class SampleDrawnTextureTest : public TestCase
630 {
631 public:
632 SampleDrawnTextureTest (tcu::TestContext& testCtx,
633 const std::string& name,
634 const std::string& description,
635 const VkFormat imageFormat,
636 const VkFormat imageViewFormat,
637 const bool twoSamplers,
638 const bool cubemap);
639
640 void initPrograms (SourceCollections& programCollection) const;
641 TestInstance* createInstance (Context& context) const;
642 virtual void checkSupport (Context& context) const;
643
644 private:
645 const VkFormat m_imageFormat;
646 const VkFormat m_imageViewFormat;
647 const bool m_twoSamplers;
648 const bool m_cubemap;
649 };
650
SampleDrawnTextureTest(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const VkFormat imageFormat,const VkFormat imageViewFormat,const bool twoSamplers,const bool cubemap)651 SampleDrawnTextureTest::SampleDrawnTextureTest (tcu::TestContext& testCtx,
652 const std::string& name,
653 const std::string& description,
654 const VkFormat imageFormat,
655 const VkFormat imageViewFormat,
656 const bool twoSamplers,
657 const bool cubemap)
658 : TestCase (testCtx, name, description)
659 , m_imageFormat (imageFormat)
660 , m_imageViewFormat (imageViewFormat)
661 , m_twoSamplers (twoSamplers)
662 , m_cubemap (cubemap)
663 {
664 }
665
checkSupport(Context & context) const666 void SampleDrawnTextureTest::checkSupport(Context& context) const
667 {
668 const auto& vki = context.getInstanceInterface();
669 const auto physicalDevice = context.getPhysicalDevice();
670 const auto usageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
671 | VK_IMAGE_USAGE_SAMPLED_BIT;
672 const bool haveMaintenance2 = context.isDeviceFunctionalitySupported("VK_KHR_maintenance2");
673
674 // Check that:
675 // - An image can be created with usage flags that are not supported by the image format
676 // but are supported by an image view created for the image.
677 // - VkImageViewUsageCreateInfo can be used to override implicit usage flags derived from the image.
678 if (!haveMaintenance2)
679 TCU_THROW(NotSupportedError, "Device does not support extended image usage flags nor overriding implicit usage flags");
680
681 VkImageFormatProperties imageFormatProperties;
682
683 if (vki.getPhysicalDeviceImageFormatProperties(physicalDevice, VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_IMAGE_TYPE_2D,
684 VK_IMAGE_TILING_OPTIMAL, usageFlags, (VkImageCreateFlags)0,
685 &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
686 TCU_THROW(NotSupportedError, "BC1 compressed texture formats not supported.");
687
688 if (vki.getPhysicalDeviceImageFormatProperties(physicalDevice, VK_FORMAT_BC3_UNORM_BLOCK, VK_IMAGE_TYPE_2D,
689 VK_IMAGE_TILING_OPTIMAL, usageFlags, (VkImageCreateFlags)0,
690 &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
691 TCU_THROW(NotSupportedError, "BC3 compressed texture formats not supported.");
692
693 if (m_cubemap && vki.getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(), m_imageFormat,
694 VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
695 usageFlags, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
696 &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
697 TCU_THROW(NotSupportedError, "Compressed images cannot be created with the VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT flag");
698 }
699
initPrograms(SourceCollections & programCollection) const700 void SampleDrawnTextureTest::initPrograms (SourceCollections& programCollection) const
701 {
702 // Pure red, green, and blue compressed with the BC1 and BC3 algorithms.
703 std::string bc1_red = "uvec4(4160813056u, 0u, 4160813056u, 0u);\n";
704 std::string bc1_blue = "uvec4(2031647, 0u, 2031647, 0u);\n";
705 std::string bc3_red = "uvec4(4294967295u, 4294967295u, 4160813056u, 0u);\n";
706 std::string bc3_blue = "uvec4(4294967295u, 4294967295u, 2031647, 0u);\n";
707
708 std::string red = (m_imageFormat == VK_FORMAT_BC1_RGB_UNORM_BLOCK) ? bc1_red : bc3_red;
709 std::string blue = (m_imageFormat == VK_FORMAT_BC1_RGB_UNORM_BLOCK) ? bc1_blue : bc3_blue;
710
711 std::ostringstream computeSrc;
712
713 // Generate the compute shader.
714 computeSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n";
715 computeSrc << "layout(set = 0, binding = 0, rgba32ui) uniform highp uimage2D img;\n";
716 computeSrc << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n";
717
718 if (!m_twoSamplers)
719 {
720 computeSrc
721 << "layout(push_constant) uniform constants {\n"
722 << " int pass;\n"
723 << "} pc;\n";
724 }
725
726 computeSrc << "void main() {\n";
727
728 if (m_twoSamplers)
729 computeSrc << " uvec4 color = " << blue;
730 else
731 {
732 computeSrc << " uvec4 color = " << red;
733 computeSrc << " if (pc.pass == 1)\n";
734 computeSrc << " color = " << blue;
735 }
736
737 computeSrc
738 << " for (int x = 0; x < " << WIDTH << "; x++)\n"
739 << " for (int y = 0; y < " << HEIGHT << "; y++)\n"
740 << " imageStore(img, ivec2(x, y), color);\n"
741 << "}\n";
742
743 // Generate the vertex shader.
744 std::ostringstream vertexSrc;
745 vertexSrc
746 << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
747 << "layout(location = 0) in highp vec4 a_position;\n"
748 << "layout(location = 1) in vec2 inTexCoord;\n"
749 << "layout(location = 1) out vec2 fragTexCoord;\n"
750 << "void main (void) {\n"
751 << " gl_Position = a_position;\n"
752 << " fragTexCoord = inTexCoord;\n"
753 << "}\n";
754
755 // Generate the fragment shader.
756 std::ostringstream fragmentSrc;
757 fragmentSrc
758 << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
759 << "layout(location = 0) out vec4 outColor;\n"
760 << "layout(location = 1) in vec2 fragTexCoord;\n";
761
762 fragmentSrc << "layout(binding = 0) uniform sampler2D compTexSampler;\n";
763
764 if (m_twoSamplers)
765 {
766 fragmentSrc
767 << "layout(binding = 1) uniform usampler2D texSampler;\n"
768 << "layout(push_constant) uniform constants {\n"
769 << " int pass;\n"
770 << "} pc;\n"
771 << "void main() {\n"
772 << " if (pc.pass == 1)\n"
773 << " outColor = texture(compTexSampler, fragTexCoord);\n"
774 << " else"
775 << " outColor = texture(texSampler, fragTexCoord);\n";
776 }
777 else
778 {
779 fragmentSrc
780 << "void main() {\n"
781 << " outColor = texture(compTexSampler, fragTexCoord);\n";
782 }
783
784 fragmentSrc << "}\n";
785
786 programCollection.glslSources.add("comp") << glu::ComputeSource(computeSrc.str());
787 programCollection.glslSources.add("vert") << glu::VertexSource(vertexSrc.str());
788 programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSrc.str());
789 }
790
createInstance(Context & context) const791 TestInstance* SampleDrawnTextureTest::createInstance (Context& context) const
792 {
793 return new SampleDrawnTextureTestInstance(context, m_imageFormat, m_imageViewFormat, m_twoSamplers, m_cubemap);
794 }
795
796 } // anonymous ns
797
createImageSampleDrawnTextureTests(tcu::TestContext & testCtx)798 tcu::TestCaseGroup* createImageSampleDrawnTextureTests (tcu::TestContext& testCtx)
799 {
800 /* If both samplers are enabled, the test works as follows:
801 *
802 * Pass 0:
803 * - Compute shader fills a storage image with values that are pure blue compressed with
804 * either the BC1 or BC3 algorithm.
805 * - Fragment shader samples the image and draws the values on a target image.
806 * - As the sampled values are accessed through an image view using an uncompressed
807 * format, they remain compressed and the drawn image ends up being garbage.
808 * Pass 1:
809 * - Fragment shader samples the image. On this pass, the image view uses
810 * a block-compressed format and correctly interprets the sampled values.
811 * - As the values are uncompressed now, the target image is filled
812 * with pure blue and the test passes.
813
814 * Only one sampler enabled:
815 * Pass 0:
816 * - Compute shader fills a storage image with values that are pure red compressed
817 * with either the BC1 or BC3 algorithm.
818 * - Fragment shader samples the image through an image view which interprets the values
819 * correctly. The values are drawn on a target image. The test doesn't pass yet
820 * since the image is red.
821 * Pass 1:
822 * - Compute shader fills the storage image with values that are pure blue compressed
823 * with the same algorithm as on the previous pass.
824 * - Fragment shader samples the image through an image view which interprets the values
825 * correctly. The values are drawn on the target image and the test passes.
826 *
827 * If cubemaps are enabled:
828 * Pass 0:
829 * - If both samplers are enabled, draw compressed pure blue on the faces. Otherwise pure red.
830 * - Sample the image through an image view with or without compressed format as in the cases
831 * without cubemaps.
832 * Pass 1:
833 * - If only one sampler is enabled, redraw the faces with pure blue
834 * - Sample the image. Sampling should produce colors with a 0.0 red component and with > 0.0
835 * blue and alpha components.
836 */
837
838 const bool twoSamplers = true;
839 const bool cubemap = true;
840
841 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "sample_texture", "Sample texture that has been rendered to tests"));
842
843 testGroup->addChild(new SampleDrawnTextureTest(testCtx, "128_bit_compressed_format_cubemap", "", VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_R32G32B32A32_UINT, !twoSamplers, cubemap));
844 testGroup->addChild(new SampleDrawnTextureTest(testCtx, "64_bit_compressed_format_cubemap", "", VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_R32G32_UINT, !twoSamplers, cubemap));
845 testGroup->addChild(new SampleDrawnTextureTest(testCtx, "64_bit_compressed_format_two_samplers_cubemap", "", VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_R32G32_UINT, twoSamplers, cubemap));
846 testGroup->addChild(new SampleDrawnTextureTest(testCtx, "128_bit_compressed_format_two_samplers_cubemap", "", VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_R32G32B32A32_UINT, twoSamplers, cubemap));
847
848 testGroup->addChild(new SampleDrawnTextureTest(testCtx, "64_bit_compressed_format", "", VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_R32G32_UINT, !twoSamplers, false));
849 testGroup->addChild(new SampleDrawnTextureTest(testCtx, "64_bit_compressed_format_two_samplers", "", VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_R32G32_UINT, twoSamplers, false));
850 testGroup->addChild(new SampleDrawnTextureTest(testCtx, "128_bit_compressed_format", "", VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_R32G32B32A32_UINT, !twoSamplers, false));
851 testGroup->addChild(new SampleDrawnTextureTest(testCtx, "128_bit_compressed_format_two_samplers", "", VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_R32G32B32A32_UINT, twoSamplers, false));
852
853 return testGroup.release();
854 }
855
856 } // image
857 } // vkt
858