1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Shader builtin variable tests.
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktShaderRenderBuiltinVarTests.hpp"
27
28 #include "tcuFloat.hpp"
29 #include "deUniquePtr.hpp"
30 #include "vkDefs.hpp"
31 #include "vktShaderRender.hpp"
32 #include "gluShaderUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include "tcuStringTemplate.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuTestLog.hpp"
37 #include "vktDrawUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkMemUtil.hpp"
41 #include "vkCmdUtil.hpp"
42
43 #include "deMath.h"
44 #include "deRandom.hpp"
45
46 #include <map>
47
48 using namespace std;
49 using namespace tcu;
50 using namespace vk;
51 using namespace de;
52
53 namespace vkt
54 {
55 using namespace drawutil;
56
57 namespace sr
58 {
59
60 namespace
61 {
62
63 enum
64 {
65 FRONTFACE_RENDERWIDTH = 16,
66 FRONTFACE_RENDERHEIGHT = 16
67 };
68
69 class FrontFacingVertexShader : public rr::VertexShader
70 {
71 public:
FrontFacingVertexShader(void)72 FrontFacingVertexShader (void)
73 : rr::VertexShader(1, 0)
74 {
75 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
76 }
77
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const78 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
79 {
80 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
81 {
82 packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
83 packets[packetNdx]->instanceNdx,
84 packets[packetNdx]->vertexNdx);
85 }
86 }
87 };
88
89 class FrontFacingFragmentShader : public rr::FragmentShader
90 {
91 public:
FrontFacingFragmentShader(void)92 FrontFacingFragmentShader (void)
93 : rr::FragmentShader(0, 1)
94 {
95 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
96 }
97
shadeFragments(rr::FragmentPacket *,const int numPackets,const rr::FragmentShadingContext & context) const98 void shadeFragments (rr::FragmentPacket* , const int numPackets, const rr::FragmentShadingContext& context) const
99 {
100 tcu::Vec4 color;
101 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
102 {
103 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
104 {
105 if (context.visibleFace == rr::FACETYPE_FRONT)
106 color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
107 else
108 color = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
109 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
110 }
111 }
112 }
113 };
114
115 class BuiltinGlFrontFacingCaseInstance : public ShaderRenderCaseInstance
116 {
117 public:
118 BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology);
119
120 TestStatus iterate (void);
121 private:
122 const VkPrimitiveTopology m_topology;
123 };
124
BuiltinGlFrontFacingCaseInstance(Context & context,VkPrimitiveTopology topology)125 BuiltinGlFrontFacingCaseInstance::BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology)
126 : ShaderRenderCaseInstance (context)
127 , m_topology (topology)
128 {
129 }
130
131
iterate(void)132 TestStatus BuiltinGlFrontFacingCaseInstance::iterate (void)
133 {
134 TestLog& log = m_context.getTestContext().getLog();
135 std::vector<Vec4> vertices;
136 std::vector<VulkanShader> shaders;
137 std::shared_ptr<rr::VertexShader> vertexShader = std::make_shared<FrontFacingVertexShader>();
138 std::shared_ptr<rr::FragmentShader> fragmentShader = std::make_shared<FrontFacingFragmentShader>();
139 std::string testDesc;
140
141 vertices.push_back(Vec4( -0.75f, -0.75f, 0.0f, 1.0f));
142 vertices.push_back(Vec4( 0.0f, -0.75f, 0.0f, 1.0f));
143 vertices.push_back(Vec4( -0.37f, 0.75f, 0.0f, 1.0f));
144 vertices.push_back(Vec4( 0.37f, 0.75f, 0.0f, 1.0f));
145 vertices.push_back(Vec4( 0.75f, -0.75f, 0.0f, 1.0f));
146 vertices.push_back(Vec4( 0.0f, -0.75f, 0.0f, 1.0f));
147
148 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vert")));
149 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("frag")));
150
151 testDesc = "gl_FrontFacing " + getPrimitiveTopologyShortName(m_topology) + " ";
152
153 FrameBufferState frameBufferState (FRONTFACE_RENDERWIDTH, FRONTFACE_RENDERHEIGHT);
154 PipelineState pipelineState (m_context.getDeviceProperties().limits.subPixelPrecisionBits);
155 DrawCallData drawCallData (m_topology, vertices);
156 VulkanProgram vulkanProgram (shaders);
157 VulkanDrawContext dc (m_context, frameBufferState);
158 dc.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
159 dc.draw();
160
161 ReferenceDrawContext refDrawContext(frameBufferState);
162 refDrawContext.registerDrawObject(pipelineState, vertexShader, fragmentShader, drawCallData);
163 refDrawContext.draw();
164
165 log << TestLog::Image( "reference",
166 "reference",
167 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
168 refDrawContext.getColorPixels().getFormat()),
169 refDrawContext.getColorPixels().getWidth(),
170 refDrawContext.getColorPixels().getHeight(),
171 1,
172 refDrawContext.getColorPixels().getDataPtr()));
173
174 log << TestLog::Image( "result",
175 "result",
176 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
177 dc.getColorPixels().getFormat()),
178 dc.getColorPixels().getWidth(),
179 dc.getColorPixels().getHeight(),
180 1,
181 dc.getColorPixels().getDataPtr()));
182
183 if (tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
184 "ComparisonResult",
185 "Image comparison result",
186 refDrawContext.getColorPixels(),
187 dc.getColorPixels(),
188 UVec4(0u),
189 IVec3(1,1,0),
190 false,
191 tcu::COMPARE_LOG_RESULT))
192 {
193 testDesc += "passed";
194 return tcu::TestStatus::pass(testDesc.c_str());
195 }
196 else
197 {
198 testDesc += "failed";
199 return tcu::TestStatus::fail(testDesc.c_str());
200 }
201 }
202
203 class BuiltinGlFrontFacingCase : public TestCase
204 {
205 public:
206 BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description);
207 virtual ~BuiltinGlFrontFacingCase (void);
208
209 void initPrograms (SourceCollections& dst) const;
210 void checkSupport (Context& context) const;
211 TestInstance* createInstance (Context& context) const;
212
213 private:
214 BuiltinGlFrontFacingCase (const BuiltinGlFrontFacingCase&); // not allowed!
215 BuiltinGlFrontFacingCase& operator= (const BuiltinGlFrontFacingCase&); // not allowed!
216
217 const VkPrimitiveTopology m_topology;
218 };
219
BuiltinGlFrontFacingCase(TestContext & testCtx,VkPrimitiveTopology topology,const char * name,const char * description)220 BuiltinGlFrontFacingCase::BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description)
221 : TestCase (testCtx, name, description)
222 , m_topology (topology)
223 {
224 }
225
~BuiltinGlFrontFacingCase(void)226 BuiltinGlFrontFacingCase::~BuiltinGlFrontFacingCase (void)
227 {
228 }
229
initPrograms(SourceCollections & programCollection) const230 void BuiltinGlFrontFacingCase::initPrograms (SourceCollections& programCollection) const
231 {
232 {
233 std::ostringstream vertexSource;
234 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
235 << "\n"
236 << "layout(location = 0) in highp vec4 position;\n"
237 << "void main()\n"
238 << "{\n"
239 << "gl_Position = position;\n"
240 << "gl_PointSize = 1.0;\n"
241 << "}\n";
242 programCollection.glslSources.add("vert") << glu::VertexSource(vertexSource.str());
243 }
244
245 {
246 std::ostringstream fragmentSource;
247 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
248 << "\n"
249 << "layout(location = 0) out mediump vec4 color;\n"
250 << "void main()\n"
251 << "{\n"
252 << "if (gl_FrontFacing)\n"
253 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
254 << "else\n"
255 << " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
256 << "}\n";
257 programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSource.str());
258 }
259 }
260
checkSupport(Context & context) const261 void BuiltinGlFrontFacingCase::checkSupport (Context& context) const
262 {
263 #ifndef CTS_USES_VULKANSC
264 if (m_topology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
265 context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
266 !context.getPortabilitySubsetFeatures().triangleFans)
267 {
268 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
269 }
270 #else
271 DE_UNREF(context);
272 #endif // CTS_USES_VULKANSC
273 }
274
createInstance(Context & context) const275 TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const
276 {
277 return new BuiltinGlFrontFacingCaseInstance(context, m_topology);
278 }
279
280 class BuiltinFragDepthCaseInstance : public TestInstance
281 {
282 public:
283 enum
284 {
285 RENDERWIDTH = 16,
286 RENDERHEIGHT = 16
287 };
288 BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples);
289 TestStatus iterate (void);
290
291 bool validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const;
292 private:
293 const VkPrimitiveTopology m_topology;
294 const VkFormat m_format;
295 const bool m_largeDepthEnable;
296 const float m_defaultDepthValue;
297 const bool m_depthClampEnable;
298 const VkSampleCountFlagBits m_samples;
299 const tcu::UVec2 m_renderSize;
300 const float m_largeDepthBase;
301 };
302
BuiltinFragDepthCaseInstance(Context & context,VkPrimitiveTopology topology,VkFormat format,bool largeDepthEnable,float defaultDepth,bool depthClampEnable,const VkSampleCountFlagBits samples)303 BuiltinFragDepthCaseInstance::BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples)
304 : TestInstance (context)
305 , m_topology (topology)
306 , m_format (format)
307 , m_largeDepthEnable (largeDepthEnable)
308 , m_defaultDepthValue (defaultDepth)
309 , m_depthClampEnable (depthClampEnable)
310 , m_samples (samples)
311 , m_renderSize (RENDERWIDTH, RENDERHEIGHT)
312 , m_largeDepthBase (20.0f)
313 {
314 const InstanceInterface& vki = m_context.getInstanceInterface();
315 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
316
317 try
318 {
319 VkImageFormatProperties imageFormatProperties;
320 VkFormatProperties formatProperties;
321
322 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE)
323 throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported");
324
325 if (m_context.getDeviceFeatures().sampleRateShading == VK_FALSE)
326 throw tcu::NotSupportedError("sampleRateShading not supported");
327
328 imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, m_format, VK_IMAGE_TYPE_2D,
329 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, (VkImageCreateFlags)0);
330
331 if ((imageFormatProperties.sampleCounts & m_samples) == 0)
332 throw tcu::NotSupportedError("Image format and sample count not supported");
333
334 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R8G8B8A8_UINT);
335
336 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
337 throw tcu::NotSupportedError("MarkerImage format not supported as storage image");
338
339 if (m_largeDepthEnable && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_depth_range_unrestricted"))
340 throw tcu::NotSupportedError("large_depth test variants require the VK_EXT_depth_range_unrestricted extension");
341
342 if (m_context.getDeviceFeatures().depthClamp == VK_FALSE && m_depthClampEnable)
343 throw tcu::NotSupportedError("Depthclamp is not supported.");
344 }
345 catch (const vk::Error& e)
346 {
347 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
348 throw tcu::NotSupportedError("Image format not supported");
349 else
350 throw;
351
352 }
353 }
354
iterate(void)355 TestStatus BuiltinFragDepthCaseInstance::iterate (void)
356 {
357 const VkDevice device = m_context.getDevice();
358 const DeviceInterface& vk = m_context.getDeviceInterface();
359 const VkQueue queue = m_context.getUniversalQueue();
360 Allocator& allocator = m_context.getDefaultAllocator();
361 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
362 TestLog& log = m_context.getTestContext().getLog();
363 const deUint32 scale = 4; // To account for std140 stride
364 const VkDeviceSize pixelCount = m_renderSize.x() * m_renderSize.y();
365 std::string testDesc;
366 Move<VkImage> depthResolveImage;
367 Move<VkImageView> depthResolveImageView;
368 MovePtr<Allocation> depthResolveAllocation;
369 Move<VkImage> depthImage;
370 Move<VkImageView> depthImageView;
371 MovePtr<Allocation> depthImageAllocation;
372 Move<VkBuffer> controlBuffer;
373 MovePtr<Allocation> controlBufferAllocation;
374 Move<VkImage> markerImage;
375 Move<VkImageView> markerImageView;
376 MovePtr<Allocation> markerImageAllocation;
377 Move<VkBuffer> markerBuffer;
378 MovePtr<Allocation> markerBufferAllocation;
379 Move<VkBuffer> validationBuffer;
380 MovePtr<Allocation> validationAlloc;
381 MovePtr<Allocation> depthInitAllocation;
382 Move<VkCommandPool> cmdPool;
383 Move<VkCommandBuffer> transferCmdBuffer;
384 Move<VkSampler> depthSampler;
385
386 // Create Buffer/Image for validation
387 {
388 VkFormat resolvedBufferFormat = VK_FORMAT_R32_SFLOAT;
389 const VkBufferCreateInfo validationBufferCreateInfo =
390 {
391 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
392 DE_NULL, // const void* pNext
393 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags
394 m_samples * pixelCount * getPixelSize(mapVkFormat(resolvedBufferFormat)), // VkDeviceSize size
395 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
396 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
397 0u, // uint32_t queueFamilyIndexCount,
398 DE_NULL // const uint32_t* pQueueFamilyIndices
399 };
400
401 validationBuffer = createBuffer(vk, device, &validationBufferCreateInfo);
402 validationAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *validationBuffer), MemoryRequirement::HostVisible);
403 VK_CHECK(vk.bindBufferMemory(device, *validationBuffer, validationAlloc->getMemory(), validationAlloc->getOffset()));
404
405 const VkImageCreateInfo depthResolveImageCreateInfo =
406 {
407 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
408 DE_NULL, // const void* pNext
409 (VkImageCreateFlags)0, // VkImageCreateFlags flags
410 VK_IMAGE_TYPE_2D, // VkIMageType imageType
411 resolvedBufferFormat, // VkFormat format
412 makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1u), // VkExtent3D extent
413 1u, // uint32_t mipLevels
414 1u, // uint32_t arrayLayers
415 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagsBits samples
416 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
417 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage
418 VK_IMAGE_USAGE_STORAGE_BIT |
419 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
420 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
421 0u, // uint32_t queueFamilyIndexCount
422 DE_NULL, // const uint32_t pQueueFamilyIndices
423 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
424 };
425
426 depthResolveImage = createImage(vk, device, &depthResolveImageCreateInfo, DE_NULL);
427 depthResolveAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthResolveImage), MemoryRequirement::Any);
428 VK_CHECK(vk.bindImageMemory(device, *depthResolveImage, depthResolveAllocation->getMemory(), depthResolveAllocation->getOffset()));
429
430 const VkImageViewCreateInfo depthResolveImageViewCreateInfo =
431 {
432 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
433 DE_NULL, // const void* pNext
434 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags
435 *depthResolveImage, // VkImage image
436 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType type
437 resolvedBufferFormat, // VkFormat format
438 makeComponentMappingRGBA(), // VkComponentMapping componentMapping
439 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u) // VkImageSUbresourceRange subresourceRange
440 };
441
442 depthResolveImageView = createImageView(vk, device, &depthResolveImageViewCreateInfo, DE_NULL);
443 }
444
445 // Marker Buffer
446 {
447 const VkDeviceSize size = m_samples * m_renderSize.x() * m_renderSize.y() * getPixelSize(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT));
448
449 const VkBufferCreateInfo markerBufferCreateInfo =
450 {
451 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
452 DE_NULL, // const void* pNext
453 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags
454 size, // VkDeviceSize size
455 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
456 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
457 0u, // uint32_t queueFamilyIndexCount
458 DE_NULL // const uint32_t* pQueueFamilyIndices
459 };
460
461 markerBuffer = createBuffer(vk, device, &markerBufferCreateInfo, DE_NULL);
462 markerBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *markerBuffer), MemoryRequirement::HostVisible);
463 VK_CHECK(vk.bindBufferMemory(device, *markerBuffer, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset()));
464
465 const VkImageCreateInfo markerImageCreateInfo =
466 {
467 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
468 DE_NULL, // const void* pNext
469 (VkImageCreateFlags)0, // VkImageCreateFlags flags
470 VK_IMAGE_TYPE_2D, // VkImageType imageType
471 VK_FORMAT_R8G8B8A8_UINT, // VkFormat format
472 makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1),// VkExtent3D extent
473 1u, // uint32_t mipLevels
474 1u, // uint32_t arrayLayers
475 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagsBit smaples
476 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
477 VK_IMAGE_USAGE_STORAGE_BIT | // VkImageUsageFlags usage
478 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
479 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
480 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharing
481 0u, // uint32_t queueFamilyIndexCount
482 DE_NULL, // const uint32_t* pQueueFamilyIndices
483 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
484 };
485
486 markerImage = createImage(vk, device, &markerImageCreateInfo, DE_NULL);
487 markerImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *markerImage), MemoryRequirement::Any);
488 VK_CHECK(vk.bindImageMemory(device, *markerImage, markerImageAllocation->getMemory(), markerImageAllocation->getOffset()));
489
490 const VkImageViewCreateInfo markerViewCreateInfo =
491 {
492 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
493 DE_NULL, // const void* pNext
494 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags
495 *markerImage, // VkImage image
496 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
497 VK_FORMAT_R8G8B8A8_UINT, // VkFormat format
498 makeComponentMappingRGBA(), // VkComponentMapping components
499 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)
500 };
501
502 markerImageView = createImageView(vk, device, &markerViewCreateInfo, DE_NULL);
503 }
504
505 // Control Buffer
506 {
507 const VkBufferCreateInfo controlBufferCreateInfo =
508 {
509 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
510 DE_NULL, // const void* pNext
511 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags
512 pixelCount * sizeof(float)* scale, // VkDeviceSize size
513 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage
514 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
515 0u, // deUint32 queueFamilyIndexCount
516
517 DE_NULL // pQueueFamilyIndices
518 };
519
520 controlBuffer = createBuffer(vk, device, &controlBufferCreateInfo, DE_NULL);
521 controlBufferAllocation = allocator.allocate( getBufferMemoryRequirements(vk, device, *controlBuffer), MemoryRequirement::HostVisible);
522 VK_CHECK(vk.bindBufferMemory(device, *controlBuffer, controlBufferAllocation->getMemory(), controlBufferAllocation->getOffset()));
523
524 {
525 float* bufferData = (float*)(controlBufferAllocation->getHostPtr());
526 float sign = m_depthClampEnable ? -1.0f : 1.0f;
527 for (deUint32 ndx = 0; ndx < m_renderSize.x() * m_renderSize.y(); ndx++)
528 {
529 bufferData[ndx * scale] = (float)ndx / 256.0f * sign;
530 if (m_largeDepthEnable)
531 bufferData[ndx * scale] += m_largeDepthBase;
532 }
533
534 const VkMappedMemoryRange range =
535 {
536 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
537 DE_NULL,
538 controlBufferAllocation->getMemory(),
539 0u,
540 VK_WHOLE_SIZE
541 };
542
543 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
544 }
545 }
546
547 // Depth Buffer
548 {
549 VkImageSubresourceRange depthSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
550 const VkImageCreateInfo depthImageCreateInfo =
551 {
552 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
553 DE_NULL, // const void* pNext
554 (VkImageCreateFlags)0, // VkImageCreateFlags flags
555 VK_IMAGE_TYPE_2D, // VkImageType imageType
556 m_format, // VkFormat format
557 makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u), // VkExtent3D extent
558 1u, // uint32_t mipLevels
559 1u, // uint32_t arrayLayers
560 m_samples, // VkSampleCountFlagsBits samples
561 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
562 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
563 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
564 VK_IMAGE_USAGE_SAMPLED_BIT |
565 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage
566 VK_SHARING_MODE_EXCLUSIVE, // VkShaderingMode sharingMode
567 0u, // uint32_t queueFamilyIndexCount
568 DE_NULL, // const uint32_t* pQueueFamilyIndices
569 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
570 };
571
572 depthImage = createImage(vk, device, &depthImageCreateInfo, DE_NULL);
573 depthImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthImage), MemoryRequirement::Any);
574 VK_CHECK(vk.bindImageMemory(device, *depthImage, depthImageAllocation->getMemory(), depthImageAllocation->getOffset()));
575
576 const VkImageViewCreateInfo imageViewParams =
577 {
578 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
579 DE_NULL, // const void* pNext;
580 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags;
581 *depthImage, // VkImage image;
582 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
583 m_format, // VkFormat format;
584 makeComponentMappingRGBA(), // VkComponentMapping components;
585 depthSubresourceRange, // VkImageSubresourceRange subresourceRange;
586 };
587 depthImageView = createImageView(vk, device, &imageViewParams);
588
589 const VkSamplerCreateInfo depthSamplerCreateInfo =
590 {
591 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
592 DE_NULL, // const void* pNext
593 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags
594 VK_FILTER_NEAREST, // VkFilter minFilter
595 VK_FILTER_NEAREST, // VkFilter magFilter
596 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipMapMode mipMapMode
597 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU
598 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV
599 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressmodeW
600 0.0f, // float mipLodBias
601 VK_FALSE, // VkBool32 anisotropyEnable
602 0.0f, // float maxAnisotropy
603 VK_FALSE, // VkBool32 compareEnable
604 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp
605 0.0f, // float minLod
606 0.0f, // float maxLod
607 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
608 VK_FALSE // VkBool32 unnormalizedCoordinates
609 };
610
611 depthSampler = createSampler(vk, device, &depthSamplerCreateInfo, DE_NULL);
612 }
613
614 // Command Pool
615 {
616 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
617 {
618 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType
619 DE_NULL, // const void* pNext
620 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags
621 queueFamilyIndex // uint32_t queueFamilyIndex
622 };
623
624 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
625 }
626
627 // Command buffer for data transfers
628 {
629 const VkCommandBufferAllocateInfo cmdBufferAllocInfo =
630 {
631 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType,
632 DE_NULL, // const void* pNext
633 *cmdPool, // VkCommandPool commandPool
634 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level
635 1u // uint32_t bufferCount
636 };
637
638 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo);
639 }
640
641 // Initialize Marker Buffer
642 {
643 const VkImageMemoryBarrier imageBarrier[] =
644 {
645 {
646 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
647 DE_NULL, // const void* pNext
648 0, // VkAccessMask srcAccessMask
649 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessMask dstAccessMask
650 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
651 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
652 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
653 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
654 *markerImage, // VkImage image
655 {
656 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
657 0u, // uint32_t baseMipLevel
658 1u, // uint32_t mipLevels
659 0u, // uint32_t baseArray
660 1u // uint32_t arraySize
661 }
662 },
663 };
664
665 const VkImageMemoryBarrier imagePostBarrier[] =
666 {
667 {
668 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
669 DE_NULL, // const void* pNext
670 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlagBits srcAccessMask
671 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlagBits dstAccessMask
672 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
673 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
674 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
675 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
676 *markerImage, // VkImage image
677 {
678 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
679 0u, // uint32_t baseMipLevel
680 1u, // uint32_t mipLevels
681 0u, // uint32_t baseArray
682 1u // uint32_t arraySize
683 }
684 },
685 };
686
687 beginCommandBuffer(vk, *transferCmdBuffer);
688 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
689 (VkDependencyFlags)0,
690 0, (const VkMemoryBarrier*)DE_NULL,
691 0, (const VkBufferMemoryBarrier*)DE_NULL,
692 DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
693
694 const VkClearValue colorClearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
695 const VkImageSubresourceRange colorClearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
696
697 vk.cmdClearColorImage(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &colorClearValue.color, 1u, &colorClearRange);
698
699 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
700 (VkDependencyFlags)0,
701 0, (const VkMemoryBarrier*)DE_NULL,
702 0, (const VkBufferMemoryBarrier*)DE_NULL,
703 DE_LENGTH_OF_ARRAY(imagePostBarrier), imagePostBarrier);
704
705 endCommandBuffer(vk, *transferCmdBuffer);
706
707 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
708 m_context.resetCommandPoolForVKSC(device, *cmdPool);
709 }
710
711
712 // Perform Draw
713 {
714 std::vector<Vec4> vertices;
715 std::vector<VulkanShader> shaders;
716 Move<VkDescriptorSetLayout> descriptorSetLayout;
717 Move<VkDescriptorPool> descriptorPool;
718 Move<VkDescriptorSet> descriptorSet;
719
720 // Descriptors
721 {
722 DescriptorSetLayoutBuilder layoutBuilder;
723 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
724 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
725 descriptorSetLayout = layoutBuilder.build(vk, device);
726 descriptorPool = DescriptorPoolBuilder()
727 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
728 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
729 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
730
731 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
732 {
733 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
734 DE_NULL,
735 *descriptorPool,
736 1u,
737 &descriptorSetLayout.get()
738 };
739
740 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
741
742 const VkDescriptorBufferInfo bufferInfo =
743 {
744 *controlBuffer,
745 0u,
746 VK_WHOLE_SIZE
747 };
748
749 const VkDescriptorImageInfo imageInfo =
750 {
751 (VkSampler)DE_NULL,
752 *markerImageView,
753 VK_IMAGE_LAYOUT_GENERAL
754 };
755
756 DescriptorSetUpdateBuilder()
757 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfo)
758 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
759 .update(vk, device);
760 }
761
762 vertices.push_back(Vec4( -0.70f, 0.5f, 0.0f, 1.0f));
763 vertices.push_back(Vec4( 0.45f, -0.75f, 0.0f, 1.0f));
764 vertices.push_back(Vec4( 0.78f, 0.0f, 0.0f, 1.0f));
765 vertices.push_back(Vec4( -0.1f, 0.6f, 0.0f, 1.0f));
766
767 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVert")));
768 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFrag")));
769
770 FrameBufferState frameBufferState(m_renderSize.x(), m_renderSize.y());
771 PipelineState pipelineState(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
772 DrawCallData drawCallData(m_topology, vertices);
773 VulkanProgram vulkanProgram(shaders);
774
775 frameBufferState.depthFormat = m_format;
776 frameBufferState.numSamples = m_samples;
777 frameBufferState.depthImageView = *depthImageView;
778 pipelineState.depthClampEnable = m_depthClampEnable;
779 pipelineState.compareOp = rr::TESTFUNC_ALWAYS;
780 pipelineState.depthTestEnable = true;
781 pipelineState.depthWriteEnable = true;
782 pipelineState.sampleShadingEnable = true;
783 vulkanProgram.descriptorSetLayout = *descriptorSetLayout;
784 vulkanProgram.descriptorSet = *descriptorSet;
785
786 VulkanDrawContext vulkanDrawContext(m_context, frameBufferState);
787 vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
788 vulkanDrawContext.draw();
789
790 log << TestLog::Image( "resultColor",
791 "Result Color Buffer",
792 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
793 vulkanDrawContext.getColorPixels().getFormat()),
794 vulkanDrawContext.getColorPixels().getWidth(),
795 vulkanDrawContext.getColorPixels().getHeight(),
796 1,
797 vulkanDrawContext.getColorPixels().getDataPtr()));
798 }
799
800 // Barrier to transition between first and second pass
801 {
802 const VkImageMemoryBarrier imageBarrier[] =
803 {
804 {
805 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
806 DE_NULL, // const void* pNext
807 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
808 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask
809 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
810 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
811 0u, // deUint32 srcQueueFamilyIndex
812 0u, // deUint32 dstQueueFamilyIndex
813 *depthImage, // VkImage image
814 {
815 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask
816 0u, // deUint32 baseMipLevel
817 1u, // deUint32 levelCount
818 0u, // deUint32 baseArrayLayer
819 1u // deUint32 layerCount
820 }
821 },
822 {
823 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
824 DE_NULL, // const void* pNext
825 0u, // VkAccessFlags srcAccessMask
826 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask
827 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
828 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
829 0u, // deUint32 srcQueueFamilyIndex
830 0u, // deUint32 dstQueueFamilyIndex
831 *depthResolveImage, // VkImage image
832 {
833 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
834 0u, // deUint32 baseMipLevel
835 1u, // deUint32 levelCount
836 0u, // deUint32 baseArrayLayer
837 1u, // deUint32 layerCount
838
839 }
840 }
841 };
842
843 beginCommandBuffer(vk, *transferCmdBuffer);
844 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_HOST_BIT,
845 (VkDependencyFlags)0,
846 0, (const VkMemoryBarrier*)DE_NULL,
847 0, (const VkBufferMemoryBarrier*)DE_NULL,
848 DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
849 endCommandBuffer(vk, *transferCmdBuffer);
850
851 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
852 m_context.resetCommandPoolForVKSC(device, *cmdPool);
853 }
854
855 // Resolve Depth Buffer
856 {
857 std::vector<Vec4> vertices;
858 std::vector<VulkanShader> shaders;
859 Move<VkDescriptorSetLayout> descriptorSetLayout;
860 Move<VkDescriptorPool> descriptorPool;
861 Move<VkDescriptorSet> descriptorSet;
862
863 // Descriptors
864 {
865 DescriptorSetLayoutBuilder layoutBuilder;
866 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
867 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
868 descriptorSetLayout = layoutBuilder.build(vk, device);
869 descriptorPool = DescriptorPoolBuilder()
870 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
871 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
872 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
873
874 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
875 {
876 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
877 DE_NULL,
878 *descriptorPool,
879 1u,
880 &descriptorSetLayout.get()
881 };
882
883 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
884
885 const VkDescriptorImageInfo depthImageInfo =
886 {
887 *depthSampler,
888 *depthImageView,
889 VK_IMAGE_LAYOUT_GENERAL
890 };
891
892 const VkDescriptorImageInfo imageInfo =
893 {
894 (VkSampler)DE_NULL,
895 *depthResolveImageView,
896 VK_IMAGE_LAYOUT_GENERAL
897 };
898
899 DescriptorSetUpdateBuilder()
900 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &depthImageInfo)
901 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
902 .update(vk, device);
903 }
904
905 vertices.push_back(Vec4( -1.0f, -1.0f, 0.0f, 1.0f));
906 vertices.push_back(Vec4( -1.0f, 1.0f, 0.0f, 1.0f));
907 vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
908 vertices.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
909
910 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVertPass2")));
911 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFragPass2")));
912
913 FrameBufferState frameBufferState(m_renderSize.x(), m_renderSize.y());
914 PipelineState pipelineState(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
915 DrawCallData drawCallData(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, vertices);
916 VulkanProgram vulkanProgram(shaders);
917
918 frameBufferState.numSamples = m_samples;
919 pipelineState.sampleShadingEnable = true;
920 vulkanProgram.descriptorSetLayout = *descriptorSetLayout;
921 vulkanProgram.descriptorSet = *descriptorSet;
922
923 VulkanDrawContext vulkanDrawContext(m_context, frameBufferState);
924 vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
925 vulkanDrawContext.draw();
926 }
927
928 // Transfer marker buffer
929 {
930 beginCommandBuffer(vk, *transferCmdBuffer);
931 copyImageToBuffer(vk, *transferCmdBuffer, *markerImage, *markerBuffer, tcu::IVec2(m_renderSize.x() * m_samples, m_renderSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
932 endCommandBuffer(vk, *transferCmdBuffer);
933
934 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
935 m_context.resetCommandPoolForVKSC(device, *cmdPool);
936 }
937
938 // Verify depth buffer
939 {
940 bool status;
941
942 beginCommandBuffer(vk, *transferCmdBuffer, 0u);
943 copyImageToBuffer(vk, *transferCmdBuffer, *depthResolveImage, *validationBuffer, tcu::IVec2(m_renderSize.x() * m_samples, m_renderSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
944 endCommandBuffer(vk, *transferCmdBuffer);
945
946 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
947 m_context.resetCommandPoolForVKSC(device, *cmdPool);
948
949 invalidateMappedMemoryRange(vk, device, validationAlloc->getMemory(), validationAlloc->getOffset(), VK_WHOLE_SIZE);
950 invalidateMappedMemoryRange(vk, device, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset(), VK_WHOLE_SIZE);
951
952 tcu::ConstPixelBufferAccess resultPixelBuffer(mapVkFormat(VK_FORMAT_R32_SFLOAT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, validationAlloc->getHostPtr());
953 tcu::ConstPixelBufferAccess markerPixelBuffer(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, markerBufferAllocation->getHostPtr());
954 status = validateDepthBuffer(resultPixelBuffer, markerPixelBuffer, 0.001f);
955 testDesc = "gl_FragDepth " + getPrimitiveTopologyShortName(m_topology) + " ";
956 if (status)
957 {
958 testDesc += "passed";
959 return tcu::TestStatus::pass(testDesc.c_str());
960 }
961 else
962 {
963 log << TestLog::Image("resultDepth", "Result Depth Buffer", resultPixelBuffer);
964 testDesc += "failed";
965 return tcu::TestStatus::fail(testDesc.c_str());
966 }
967 }
968 }
969
validateDepthBuffer(const tcu::ConstPixelBufferAccess & validationBuffer,const tcu::ConstPixelBufferAccess & markerBuffer,const float tolerance) const970 bool BuiltinFragDepthCaseInstance::validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const
971 {
972 TestLog& log = m_context.getTestContext().getLog();
973
974 for (deUint32 rowNdx = 0; rowNdx < m_renderSize.y(); rowNdx++)
975 {
976 for (deUint32 colNdx = 0; colNdx < m_renderSize.x(); colNdx++)
977 {
978 const float multiplier = m_depthClampEnable ? 0.0f : 1.0f;
979 float expectedValue = (float)(rowNdx * m_renderSize.x() + colNdx)/256.0f * multiplier;
980
981 if (m_largeDepthEnable)
982 expectedValue += m_largeDepthBase;
983
984 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_samples; sampleNdx++)
985 {
986 const float actualValue = validationBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
987 const float markerValue = markerBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
988
989 if (markerValue != 0)
990 {
991 if (de::abs(expectedValue - actualValue) > tolerance)
992 {
993 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
994 return false;
995 }
996 }
997 else
998 {
999 if (de::abs(actualValue - m_defaultDepthValue) > tolerance)
1000 {
1001 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
1002 return false;
1003 }
1004 }
1005 }
1006 }
1007 }
1008
1009 return true;
1010 }
1011
1012 class BuiltinFragCoordMsaaCaseInstance : public TestInstance
1013 {
1014 public:
1015 enum
1016 {
1017 RENDERWIDTH = 16,
1018 RENDERHEIGHT = 16
1019 };
1020 BuiltinFragCoordMsaaCaseInstance (Context& context, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useEnable);
1021 TestStatus iterate (void);
1022 private:
1023 bool validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const;
1024
1025 const tcu::UVec2 m_renderSize;
1026 const VkSampleCountFlagBits m_sampleCount;
1027 const bool m_sampleShading;
1028 const std::vector<uint32_t> m_sampleMaskArray;
1029 const bool m_useEnable;
1030 };
1031
BuiltinFragCoordMsaaCaseInstance(Context & context,VkSampleCountFlagBits sampleCount,bool sampleShading,std::vector<uint32_t> sampleMaskArray,bool useEnable)1032 BuiltinFragCoordMsaaCaseInstance::BuiltinFragCoordMsaaCaseInstance (Context& context, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useEnable)
1033 : TestInstance (context)
1034 , m_renderSize (RENDERWIDTH, RENDERHEIGHT)
1035 , m_sampleCount (sampleCount)
1036 , m_sampleShading (sampleShading)
1037 , m_sampleMaskArray (sampleMaskArray)
1038 , m_useEnable (useEnable)
1039 {
1040 const InstanceInterface& vki = m_context.getInstanceInterface();
1041 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1042
1043 if (!context.getDeviceFeatures().sampleRateShading)
1044 TCU_THROW(NotSupportedError, "sampleRateShading not supported");
1045
1046 try
1047 {
1048 VkImageFormatProperties imageFormatProperties;
1049 VkFormatProperties formatProperties;
1050
1051 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE)
1052 throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported");
1053
1054 if (m_context.getDeviceFeatures().sampleRateShading == VK_FALSE)
1055 throw tcu::NotSupportedError("sampleRateShading not supported");
1056
1057 imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_TYPE_2D,
1058 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, (VkImageCreateFlags)0);
1059
1060 if ((imageFormatProperties.sampleCounts & m_sampleCount) == 0)
1061 throw tcu::NotSupportedError("Image format and sample count not supported");
1062
1063 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT);
1064
1065 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
1066 throw tcu::NotSupportedError("Output format not supported as storage image");
1067 }
1068 catch (const vk::Error& e)
1069 {
1070 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
1071 throw tcu::NotSupportedError("Image format not supported");
1072 else
1073 throw;
1074
1075 }
1076 }
1077
iterate(void)1078 TestStatus BuiltinFragCoordMsaaCaseInstance::iterate (void)
1079 {
1080 const VkDevice device = m_context.getDevice();
1081 const DeviceInterface& vk = m_context.getDeviceInterface();
1082 const VkQueue queue = m_context.getUniversalQueue();
1083 Allocator& allocator = m_context.getDefaultAllocator();
1084 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1085 TestLog& log = m_context.getTestContext().getLog();
1086 Move<VkImage> outputImage;
1087 Move<VkImageView> outputImageView;
1088 MovePtr<Allocation> outputImageAllocation;
1089 Move<VkDescriptorSetLayout> descriptorSetLayout;
1090 Move<VkDescriptorPool> descriptorPool;
1091 Move<VkDescriptorSet> descriptorSet;
1092 Move<VkBuffer> sampleLocationBuffer;
1093 MovePtr<Allocation> sampleLocationBufferAllocation;
1094 Move<VkCommandPool> cmdPool;
1095 Move<VkCommandBuffer> transferCmdBuffer;
1096
1097 // Coordinate result image
1098 {
1099 const VkImageCreateInfo outputImageCreateInfo =
1100 {
1101 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1102 DE_NULL, // const void* pNext
1103 (VkImageCreateFlags)0, // VkImageCreateFlags flags
1104 VK_IMAGE_TYPE_2D, // VkImageType imageType
1105 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
1106 makeExtent3D(m_sampleCount * m_renderSize.x(), m_renderSize.y(), 1u), // VkExtent3D extent3d
1107 1u, // uint32_t mipLevels
1108 1u, // uint32_t arrayLayers
1109 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1110 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1111 VK_IMAGE_USAGE_STORAGE_BIT | // VkImageUsageFlags usage
1112 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1113 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1114 0u, // uint32_t queueFamilyIndexCount
1115 DE_NULL, // const uint32_t* pQueueFamilyIndices
1116 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1117 };
1118
1119 outputImage = createImage(vk, device, &outputImageCreateInfo, DE_NULL);
1120 outputImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *outputImage), MemoryRequirement::Any);
1121 vk.bindImageMemory(device, *outputImage, outputImageAllocation->getMemory(), outputImageAllocation->getOffset());
1122
1123 VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1124 const VkImageViewCreateInfo outputImageViewCreateInfo =
1125 {
1126 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
1127 DE_NULL, // const void* pNext
1128 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags
1129 *outputImage, // VkImage image
1130 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
1131 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format,
1132 makeComponentMappingRGBA(), // VkComponentMapping components
1133 imageSubresourceRange // VkImageSubresourceRange imageSubresourceRange
1134 };
1135
1136 outputImageView = createImageView(vk, device, &outputImageViewCreateInfo);
1137 }
1138
1139 // Validation buffer
1140 {
1141 VkDeviceSize pixelSize = getPixelSize(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT));
1142 const VkBufferCreateInfo sampleLocationBufferCreateInfo =
1143 {
1144 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
1145 DE_NULL, // const void* pNext
1146 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags
1147 m_sampleCount * m_renderSize.x() * m_renderSize.y() * pixelSize, // VkDeviceSize size
1148 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
1149 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode mode
1150 0u, // uint32_t queueFamilyIndexCount
1151 DE_NULL // const uint32_t* pQueueFamilyIndices
1152 };
1153
1154 sampleLocationBuffer = createBuffer(vk, device, &sampleLocationBufferCreateInfo, DE_NULL);
1155 sampleLocationBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *sampleLocationBuffer), MemoryRequirement::HostVisible);
1156 vk.bindBufferMemory(device, *sampleLocationBuffer, sampleLocationBufferAllocation->getMemory(), sampleLocationBufferAllocation->getOffset());
1157 }
1158
1159 // Descriptors
1160 {
1161 DescriptorSetLayoutBuilder layoutBuilder;
1162 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
1163 descriptorSetLayout = layoutBuilder.build(vk, device);
1164 descriptorPool = DescriptorPoolBuilder()
1165 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1166 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1167
1168 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
1169 {
1170 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1171 DE_NULL,
1172 *descriptorPool,
1173 1u,
1174 &*descriptorSetLayout
1175 };
1176
1177 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
1178
1179 const VkDescriptorImageInfo imageInfo =
1180 {
1181 (VkSampler)DE_NULL,
1182 *outputImageView,
1183 VK_IMAGE_LAYOUT_GENERAL
1184 };
1185
1186 DescriptorSetUpdateBuilder()
1187 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
1188 .update(vk, device);
1189 }
1190
1191 // Command Pool
1192 {
1193 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
1194 {
1195 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType
1196 DE_NULL, // const void* pNext
1197 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags
1198 queueFamilyIndex // uint32_t queueFamilyIndex
1199 };
1200
1201 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
1202 }
1203
1204 // Command buffer for data transfers
1205 {
1206 const VkCommandBufferAllocateInfo cmdBufferAllocInfo =
1207 {
1208 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType,
1209 DE_NULL, // const void* pNext
1210 *cmdPool, // VkCommandPool commandPool
1211 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level
1212 1u // uint32_t bufferCount
1213 };
1214
1215 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo);
1216 }
1217
1218 // Transition the output image to LAYOUT_GENERAL
1219 {
1220 const VkImageMemoryBarrier barrier =
1221 {
1222 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1223 DE_NULL, // const void* pNext
1224 0u, // VkAccessFlags srcAccessMask
1225 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask
1226 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1227 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
1228 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1229 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1230 *outputImage, // VkImage image
1231 {
1232 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1233 0u, // uint32_t baseMipLevel
1234 1u, // uint32_t mipLevels
1235 0u, // uint32_t baseArray
1236 1u // uint32_t arraySize
1237 }
1238 };
1239
1240 beginCommandBuffer(vk, *transferCmdBuffer);
1241 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1242 (VkDependencyFlags)0,
1243 0, (const VkMemoryBarrier*)DE_NULL,
1244 0, (const VkBufferMemoryBarrier*)DE_NULL,
1245 1, &barrier);
1246
1247 endCommandBuffer(vk, *transferCmdBuffer);
1248
1249 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
1250 m_context.resetCommandPoolForVKSC(device, *cmdPool);
1251 }
1252
1253 // Perform draw
1254 {
1255 std::vector<Vec4> vertices;
1256 std::vector<VulkanShader> shaders;
1257
1258 vertices.push_back(Vec4( -1.0f, -1.0f, 0.0f, 1.0f));
1259 vertices.push_back(Vec4( -1.0f, 1.0f, 0.0f, 1.0f));
1260 vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
1261 vertices.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
1262
1263 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragCoordMsaaVert")));
1264 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragCoordMsaaFrag")));
1265
1266 FrameBufferState frameBufferState(m_renderSize.x(), m_renderSize.y());
1267 PipelineState pipelineState(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1268 DrawCallData drawCallData(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, vertices);
1269 VulkanProgram vulkanProgram(shaders);
1270
1271 frameBufferState.numSamples = m_sampleCount;
1272 pipelineState.sampleShadingEnable = m_useEnable; // When m_useEnable is false, we rely on the gl_SampleID input to enable sample shading
1273 pipelineState.sampleMasks = m_sampleMaskArray;
1274 vulkanProgram.descriptorSetLayout = *descriptorSetLayout;
1275 vulkanProgram.descriptorSet = *descriptorSet;
1276
1277 VulkanDrawContext vulkanDrawContext(m_context, frameBufferState);
1278 vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
1279 vulkanDrawContext.draw();
1280
1281 log << TestLog::Image( "result",
1282 "result",
1283 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1284 vulkanDrawContext.getColorPixels().getFormat()),
1285 vulkanDrawContext.getColorPixels().getWidth(),
1286 vulkanDrawContext.getColorPixels().getHeight(),
1287 1,
1288 vulkanDrawContext.getColorPixels().getDataPtr()));
1289 }
1290
1291 // Transfer location image to buffer
1292 {
1293 beginCommandBuffer(vk, *transferCmdBuffer);
1294 copyImageToBuffer(vk, *transferCmdBuffer, *outputImage, *sampleLocationBuffer, tcu::IVec2(m_renderSize.x() * m_sampleCount, m_renderSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
1295 endCommandBuffer(vk, *transferCmdBuffer);
1296
1297 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
1298 m_context.resetCommandPoolForVKSC(device, *cmdPool);
1299
1300 invalidateAlloc(vk, device, *sampleLocationBufferAllocation);
1301 }
1302
1303 // Validate result
1304 {
1305 bool status;
1306
1307 ConstPixelBufferAccess sampleLocationPixelBuffer(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_sampleCount * m_renderSize.x(),
1308 m_renderSize.y(), 1u, sampleLocationBufferAllocation->getHostPtr());
1309
1310 status = validateSampleLocations(sampleLocationPixelBuffer);
1311 if (status)
1312 return TestStatus::pass("FragCoordMsaa passed");
1313 else
1314 return TestStatus::fail("FragCoordMsaa failed");
1315 }
1316 }
1317
pixelOffsetCompare(const Vec2 & a,const Vec2 & b)1318 static bool pixelOffsetCompare (const Vec2& a, const Vec2& b)
1319 {
1320 return a.x() < b.x();
1321 }
1322
validateSampleLocations(const ConstPixelBufferAccess & sampleLocationBuffer) const1323 bool BuiltinFragCoordMsaaCaseInstance::validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const
1324 {
1325 const InstanceInterface& vki = m_context.getInstanceInterface();
1326 TestLog& log = m_context.getTestContext().getLog();
1327 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1328 deUint32 logSampleCount = deLog2Floor32(m_sampleCount);
1329 VkPhysicalDeviceProperties physicalDeviceProperties;
1330
1331 static const Vec2 sampleCount1Bit[] =
1332 {
1333 Vec2(0.5f, 0.5f)
1334 };
1335
1336 static const Vec2 sampleCount2Bit[] =
1337 {
1338 Vec2(0.25f, 0.25f), Vec2(0.75f, 0.75f)
1339 };
1340
1341 static const Vec2 sampleCount4Bit[] =
1342 {
1343 Vec2(0.375f, 0.125f), Vec2(0.875f, 0.375f), Vec2(0.125f, 0.625f), Vec2(0.625f, 0.875f)
1344 };
1345
1346 static const Vec2 sampleCount8Bit[] =
1347 {
1348 Vec2(0.5625f, 0.3125f), Vec2(0.4375f, 0.6875f), Vec2(0.8125f,0.5625f), Vec2(0.3125f, 0.1875f),
1349 Vec2(0.1875f, 0.8125f), Vec2(0.0625f, 0.4375f), Vec2(0.6875f,0.9375f), Vec2(0.9375f, 0.0625f)
1350 };
1351
1352 static const Vec2 sampleCount16Bit[] =
1353 {
1354 Vec2(0.5625f, 0.5625f), Vec2(0.4375f, 0.3125f), Vec2(0.3125f,0.6250f), Vec2(0.7500f, 0.4375f),
1355 Vec2(0.1875f, 0.3750f), Vec2(0.6250f, 0.8125f), Vec2(0.8125f,0.6875f), Vec2(0.6875f, 0.1875f),
1356 Vec2(0.3750f, 0.8750f), Vec2(0.5000f, 0.0625f), Vec2(0.2500f,0.1250f), Vec2(0.1250f, 0.7500f),
1357 Vec2(0.0000f, 0.5000f), Vec2(0.9375f, 0.2500f), Vec2(0.8750f,0.9375f), Vec2(0.0625f, 0.0000f)
1358 };
1359
1360 static const Vec2* standardSampleLocationTable[] =
1361 {
1362 sampleCount1Bit,
1363 sampleCount2Bit,
1364 sampleCount4Bit,
1365 sampleCount8Bit,
1366 sampleCount16Bit
1367 };
1368
1369 vki.getPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);
1370
1371 for (deInt32 rowNdx = 0; rowNdx < (deInt32)m_renderSize.y(); rowNdx++)
1372 {
1373 for (deInt32 colNdx = 0; colNdx < (deInt32)m_renderSize.x(); colNdx++)
1374 {
1375 // Check standard sample locations
1376 if (m_sampleShading == true)
1377 {
1378 std::vector<Vec2> locations;
1379
1380 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++)
1381 {
1382 const UVec2 pixelAddress = UVec2(sampleNdx + m_sampleCount * colNdx, rowNdx);
1383 const Vec4 pixelData = sampleLocationBuffer.getPixel(pixelAddress.x(), pixelAddress.y());
1384
1385 if (pixelData.z() != 0.0f)
1386 {
1387 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .z component, expected: 0.0, got: " << pixelData.z() << TestLog::EndMessage;
1388 return false;
1389 }
1390
1391 if (pixelData.w() != 1.0f)
1392 {
1393 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .w component, expected: 1.0, got: " << pixelData.w() << TestLog::EndMessage;
1394 return false;
1395 }
1396
1397 locations.push_back(Vec2(pixelData.x(), pixelData.y()));
1398 }
1399 std::sort(locations.begin(), locations.end(), pixelOffsetCompare);
1400 for (std::vector<Vec2>::const_iterator sampleIt = locations.begin(); sampleIt != locations.end(); sampleIt++)
1401 {
1402 IVec2 sampleFloor(deFloorFloatToInt32((*sampleIt).x()), deFloorFloatToInt32((*sampleIt).y()));
1403 IVec2 sampleCeil(deCeilFloatToInt32((*sampleIt).x()), deCeilFloatToInt32((*sampleIt).y()));
1404
1405 if ((sampleFloor.x() < colNdx) || (sampleCeil.x() > colNdx + 1) || (sampleFloor.y() < rowNdx) || (sampleCeil.y() > rowNdx + 1))
1406 {
1407 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): " << *sampleIt << TestLog::EndMessage;
1408 return false;
1409 }
1410 }
1411
1412 std::vector<Vec2>::iterator last = std::unique(locations.begin(), locations.end());
1413 if (last != locations.end())
1414 {
1415 log << TestLog::Message << "Fail: Sample locations contains non-unique entry" << TestLog::EndMessage;
1416 return false;
1417 }
1418
1419 if (logSampleCount < DE_LENGTH_OF_ARRAY(standardSampleLocationTable))
1420 {
1421 if (physicalDeviceProperties.limits.standardSampleLocations)
1422 {
1423 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++)
1424 {
1425 if (!de::contains(locations.begin(), locations.end(), standardSampleLocationTable[logSampleCount][sampleNdx] + Vec2(float(colNdx), float(rowNdx))))
1426 {
1427 log << TestLog::Message << "Didn't match sample locations " << standardSampleLocationTable[logSampleCount][sampleNdx] << TestLog::EndMessage;
1428 return false;
1429 }
1430 }
1431 }
1432 }
1433 }
1434 else
1435 {
1436 // Check the sample location is at the pixel center when sample shading is disabled.
1437 const Vec4 pixelData = sampleLocationBuffer.getPixel(colNdx, rowNdx);
1438
1439 if (pixelData.z() != 0.0f)
1440 {
1441 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .z component, expected: 0.0, got: " << pixelData.z() << TestLog::EndMessage;
1442 return false;
1443 }
1444
1445 if (pixelData.w() != 1.0f)
1446 {
1447 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .w component, expected: 1.0, got: " << pixelData.w() << TestLog::EndMessage;
1448 return false;
1449 }
1450
1451 if (!(deFloatFrac(pixelData.x()) == 0.5f && deFloatFrac(pixelData.y()) == 0.5f))
1452 {
1453 log << TestLog::Message << "Didn't match sample locations (" << pixelData.x() << ", " << pixelData.y() << "): " << Vec2(float(colNdx) + 0.5f, float(rowNdx) + 0.5f) << TestLog::EndMessage;
1454 return false;
1455 }
1456 }
1457 }
1458 }
1459
1460 return true;
1461 }
1462
1463 class BuiltinFragCoordMsaaTestCase : public TestCase
1464 {
1465 public:
1466 BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useCentroid, bool useEnable);
1467 virtual ~BuiltinFragCoordMsaaTestCase (void);
1468 void initPrograms (SourceCollections& sourceCollections) const;
1469 TestInstance* createInstance (Context& context) const;
1470 private:
1471 const VkSampleCountFlagBits m_sampleCount;
1472 const bool m_sampleShading; // Enable or disable Sample Shading.
1473 const std::vector<uint32_t> m_sampleMaskArray;
1474 const bool m_useCentroid; // Use Centroid interpolation decoration.
1475 const bool m_useEnable;
1476 };
1477
BuiltinFragCoordMsaaTestCase(TestContext & testCtx,const char * name,const char * description,VkSampleCountFlagBits sampleCount,bool sampleShading,std::vector<uint32_t> sampleMaskArray,bool useCentroid,bool useEnable)1478 BuiltinFragCoordMsaaTestCase::BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useCentroid, bool useEnable)
1479 : TestCase (testCtx, name, description)
1480 , m_sampleCount (sampleCount)
1481 , m_sampleShading (sampleShading)
1482 , m_sampleMaskArray (sampleMaskArray)
1483 , m_useCentroid (useCentroid)
1484 , m_useEnable (useEnable)
1485 {
1486 }
1487
~BuiltinFragCoordMsaaTestCase(void)1488 BuiltinFragCoordMsaaTestCase::~BuiltinFragCoordMsaaTestCase (void)
1489 {
1490 }
1491
initPrograms(SourceCollections & programCollection) const1492 void BuiltinFragCoordMsaaTestCase::initPrograms (SourceCollections& programCollection) const
1493 {
1494 {
1495 std::ostringstream vertexSource;
1496 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1497 << "\n"
1498 << "layout (location = 0) in vec4 position;\n"
1499 << "void main()\n"
1500 << "{\n"
1501 << " gl_Position = position;\n"
1502 << "}\n";
1503 programCollection.glslSources.add("FragCoordMsaaVert") << glu::VertexSource(vertexSource.str());
1504 }
1505
1506 if(m_sampleShading == true)
1507 {
1508 std::ostringstream fragmentSource;
1509 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1510 << "\n"
1511 << "layout(location = 0) out mediump vec4 color;\n"
1512 << "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n"
1513 << "void main()\n"
1514 << "{\n"
1515 << " const int sampleNdx = int(gl_SampleID);\n"
1516 << " ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_sampleCount << ", int(gl_FragCoord.y));\n"
1517 << " imageStore(storageImage, imageCoord, gl_FragCoord);\n"
1518 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1519 << "}\n";
1520 programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(fragmentSource.str());
1521 }
1522 else
1523 {
1524 if (m_useCentroid == false)
1525 {
1526 std::ostringstream src;
1527
1528 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1529 << "\n"
1530 << "layout (location = 0) out mediump vec4 color;\n"
1531 << "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n"
1532 << "void main()\n"
1533 << "{\n"
1534 << " ivec2 imageCoord = ivec2(int(gl_FragCoord.x), int(gl_FragCoord.y));\n"
1535 << " imageStore(storageImage, imageCoord, gl_FragCoord);\n"
1536 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1537 << "}\n";
1538
1539 programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(src.str());
1540 }
1541 else
1542 {
1543 // This SPIR-V shader is identical to GLSL shader above but with the exception of that added cendroid decoration line.
1544 std::ostringstream src;
1545 src << "; SPIR - V\n"
1546 << "; Version: 1.0\n"
1547 << "; Generator: Khronos Glslang Reference Front End; 10\n"
1548 << "; Bound: 36\n"
1549 << "; Schema: 0\n"
1550 << "OpCapability Shader\n"
1551 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1552 << "OpMemoryModel Logical GLSL450\n"
1553 << "OpEntryPoint Fragment %main \"main\" %gl_FragCoord %color\n"
1554 << "OpExecutionMode %main OriginUpperLeft\n"
1555 << "OpSource GLSL 450\n"
1556 << "OpName %main \"main\"\n"
1557 << "OpName %imageCoord \"imageCoord\"\n"
1558 << "OpName %gl_FragCoord \"gl_FragCoord\"\n"
1559 << "OpName %storageImage \"storageImage\"\n"
1560 << "OpName %color \"color\"\n"
1561 << "OpDecorate %gl_FragCoord BuiltIn FragCoord\n"
1562 << "OpDecorate %gl_FragCoord Centroid\n"
1563 << "OpDecorate %storageImage DescriptorSet 0\n"
1564 << "OpDecorate %storageImage Binding 0\n"
1565 << "OpDecorate %storageImage NonReadable\n"
1566 << "OpDecorate %color RelaxedPrecision\n"
1567 << "OpDecorate %color Location 0\n"
1568 << "%void = OpTypeVoid\n"
1569 << "%3 = OpTypeFunction %void\n"
1570 << "%int = OpTypeInt 32 1\n"
1571 << "%v2int = OpTypeVector %int 2\n"
1572 << "%_ptr_Function_v2int = OpTypePointer Function %v2int\n"
1573 << "%float = OpTypeFloat 32\n"
1574 << "%v4float = OpTypeVector %float 4\n"
1575 << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n"
1576 << "%gl_FragCoord = OpVariable %_ptr_Input_v4float Input\n"
1577 << "%uint = OpTypeInt 32 0\n"
1578 << "%uint_0 = OpConstant %uint 0\n"
1579 << "%_ptr_Input_float = OpTypePointer Input %float\n"
1580 << "%uint_1 = OpConstant %uint 1\n"
1581 << "%25 = OpTypeImage %float 2D 0 0 0 2 Rgba32f\n"
1582 << "%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25\n"
1583 << "%storageImage = OpVariable %_ptr_UniformConstant_25 UniformConstant\n"
1584 << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n"
1585 << "%color = OpVariable %_ptr_Output_v4float Output\n"
1586 << "%float_1 = OpConstant %float 1\n"
1587 << "%float_0 = OpConstant %float 0\n"
1588 << "%35 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1\n"
1589 << "%main = OpFunction %void None %3\n"
1590 << "%5 = OpLabel\n"
1591 << "%imageCoord = OpVariable %_ptr_Function_v2int Function\n"
1592 << "%17 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0\n"
1593 << "%18 = OpLoad %float %17\n"
1594 << "%19 = OpConvertFToS %int %18\n"
1595 << "%21 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_1\n"
1596 << "%22 = OpLoad %float %21\n"
1597 << "%23 = OpConvertFToS %int %22\n"
1598 << "%24 = OpCompositeConstruct %v2int %19 %23\n"
1599 << "OpStore %imageCoord %24\n"
1600 << "%28 = OpLoad %25 %storageImage\n"
1601 << "%29 = OpLoad %v2int %imageCoord\n"
1602 << "%30 = OpLoad %v4float %gl_FragCoord\n"
1603 << "OpImageWrite %28 %29 %30\n"
1604 << "OpStore %color %35\n"
1605 << "OpReturn\n"
1606 << "OpFunctionEnd\n";
1607
1608 programCollection.spirvAsmSources.add("FragCoordMsaaFrag") << src.str();
1609 }
1610 }
1611 }
1612
createInstance(Context & context) const1613 TestInstance* BuiltinFragCoordMsaaTestCase::createInstance (Context& context) const
1614 {
1615 return new BuiltinFragCoordMsaaCaseInstance(context, m_sampleCount, m_sampleShading, m_sampleMaskArray, m_useEnable);
1616 }
1617
1618 class BuiltinFragDepthCase : public TestCase
1619 {
1620 public:
1621 BuiltinFragDepthCase (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples);
1622 virtual ~BuiltinFragDepthCase (void);
1623
1624 void initPrograms (SourceCollections& dst) const;
1625 TestInstance* createInstance (Context& context) const;
1626
1627 private:
1628 const VkPrimitiveTopology m_topology;
1629 const VkFormat m_format;
1630 const bool m_largeDepthEnable;
1631 const float m_defaultDepth;
1632 const bool m_depthClampEnable;
1633 const VkSampleCountFlagBits m_samples;
1634 };
1635
BuiltinFragDepthCase(TestContext & testCtx,const char * name,const char * description,VkPrimitiveTopology topology,VkFormat format,bool largeDepthEnable,bool depthClampEnable,const VkSampleCountFlagBits samples)1636 BuiltinFragDepthCase::BuiltinFragDepthCase (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples)
1637 : TestCase (testCtx, name, description)
1638 , m_topology (topology)
1639 , m_format (format)
1640 , m_largeDepthEnable (largeDepthEnable)
1641 , m_defaultDepth (0.0f)
1642 , m_depthClampEnable (depthClampEnable)
1643 , m_samples (samples)
1644 {
1645 }
1646
~BuiltinFragDepthCase(void)1647 BuiltinFragDepthCase::~BuiltinFragDepthCase(void)
1648 {
1649 }
1650
initPrograms(SourceCollections & programCollection) const1651 void BuiltinFragDepthCase::initPrograms (SourceCollections& programCollection) const
1652 {
1653 // Vertex
1654 {
1655 // Pass 1
1656 {
1657 std::ostringstream vertexSource;
1658 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1659 << "\n"
1660 << "layout (location = 0) in vec4 position;\n"
1661 << "void main()\n"
1662 << "{\n"
1663 << " gl_Position = position;\n"
1664 << " gl_PointSize = 1.0;\n"
1665 << "}\n";
1666 programCollection.glslSources.add("FragDepthVert") << glu::VertexSource(vertexSource.str());
1667 }
1668
1669 // Pass 2
1670 {
1671 std::ostringstream vertexSource;
1672 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1673 << "\n"
1674 << "layout (location = 0) in vec4 position;\n"
1675 << "layout (location = 1) out vec2 texCoord;\n"
1676 << "void main()\n"
1677 << "{\n"
1678 << " gl_Position = position;\n"
1679 << " gl_PointSize = 1.0;\n"
1680 << " texCoord = position.xy/2 + vec2(0.5);\n"
1681 << "}\n";
1682 programCollection.glslSources.add("FragDepthVertPass2") << glu::VertexSource(vertexSource.str());
1683 }
1684 }
1685
1686 // Fragment
1687 {
1688 // Pass 1
1689 {
1690 std::ostringstream fragmentSource;
1691 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1692 << "\n"
1693 << "layout(location = 0) out mediump vec4 color;\n"
1694 << "layout (std140, set = 0, binding = 0) uniform control_buffer_t\n"
1695 << "{\n"
1696 << " float data[256];\n"
1697 << "} control_buffer;\n"
1698 << "layout (set = 0, binding = 1, rgba8ui) writeonly uniform uimage2D storageImage;\n"
1699 << "float controlDepthValue;\n"
1700 << "void recheck(float controlDepthValue)\n"
1701 << "{\n"
1702 << " if (gl_FragDepth != controlDepthValue)\n"
1703 << " gl_FragDepth = 1.0;\n"
1704 << "}\n"
1705 << "void main()\n"
1706 << "{\n"
1707 << " const int numSamples = " << m_samples << ";\n"
1708 << " if (int(gl_FragCoord.x) == " << BuiltinFragDepthCaseInstance::RENDERWIDTH/4 << ")\n"
1709 << " discard;\n"
1710 << " highp int index =int(gl_FragCoord.y) * " << BuiltinFragDepthCaseInstance::RENDERHEIGHT << " + int(gl_FragCoord.x);\n"
1711 << " controlDepthValue = control_buffer.data[index];\n"
1712 << " gl_FragDepth = controlDepthValue;\n"
1713 << " const int sampleNdx = int(gl_SampleID);\n"
1714 << " ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_samples << ", int(gl_FragCoord.y));\n"
1715 << " imageStore(storageImage, imageCoord, uvec4(1));\n"
1716 << " recheck(controlDepthValue);\n"
1717 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1718 << "}\n";
1719 programCollection.glslSources.add("FragDepthFrag") << glu::FragmentSource(fragmentSource.str());
1720 }
1721
1722 // Pass 2
1723 {
1724 const char* multisampleDecoration = m_samples != VK_SAMPLE_COUNT_1_BIT ? "MS" : "";
1725 std::ostringstream fragmentSource;
1726 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1727 << "\n"
1728 << "layout (location = 0) out mediump vec4 color;\n"
1729 << "layout (location = 1) in vec2 texCoord;\n"
1730 << "layout (binding = 0, set = 0) uniform sampler2D" << multisampleDecoration << " u_depthTex;\n"
1731 << "layout (binding = 1, set = 0, r32f) writeonly uniform image2D u_outImage;\n"
1732 << "void main (void)\n"
1733 << "{\n"
1734 << " const int numSamples = " << m_samples << ";\n"
1735 << " const int sampleNdx = int(gl_SampleID);\n"
1736 << " ivec2 renderSize = ivec2(" << BuiltinFragDepthCaseInstance::RENDERWIDTH << "," << BuiltinFragDepthCaseInstance::RENDERHEIGHT << ");\n"
1737 << " ivec2 imageCoord = ivec2(int(texCoord.x * renderSize.x), int(texCoord.y * renderSize.y));\n"
1738 << " vec4 depthVal = texelFetch(u_depthTex, imageCoord, sampleNdx);\n"
1739 << " imageStore(u_outImage, ivec2(sampleNdx + int(texCoord.x * renderSize.x) * numSamples, int(texCoord.y * renderSize.y)), depthVal);\n"
1740 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1741 << "}\n";
1742 programCollection.glslSources.add("FragDepthFragPass2") << glu::FragmentSource(fragmentSource.str());
1743 }
1744 }
1745 }
1746
createInstance(Context & context) const1747 TestInstance* BuiltinFragDepthCase::createInstance (Context& context) const
1748 {
1749 return new BuiltinFragDepthCaseInstance(context, m_topology, m_format, m_largeDepthEnable, m_defaultDepth, m_depthClampEnable, m_samples);
1750 }
1751
1752 class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance
1753 {
1754 public:
1755 BuiltinGlFragCoordXYZCaseInstance (Context& context);
1756
1757 TestStatus iterate (void);
1758 virtual void setupDefaultInputs (void);
1759 };
1760
BuiltinGlFragCoordXYZCaseInstance(Context & context)1761 BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context)
1762 : ShaderRenderCaseInstance (context)
1763 {
1764 m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM;
1765 }
1766
iterate(void)1767 TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void)
1768 {
1769 const UVec2 viewportSize = getViewportSize();
1770 const int width = viewportSize.x();
1771 const int height = viewportSize.y();
1772 const tcu::Vec3 scale (1.0f / float(width), 1.0f / float(height), 1.0f);
1773 const float precision = 0.00001f;
1774 const deUint16 indices[6] =
1775 {
1776 2, 1, 3,
1777 0, 1, 2,
1778 };
1779
1780 setup();
1781 addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
1782
1783 render(4, 2, indices);
1784
1785 // Reference image
1786 for (int y = 0; y < height; y++)
1787 {
1788 for (int x = 0; x < width; x++)
1789 {
1790 const float xf = (float(x) + .5f) / float(width);
1791 const float yf = (float(height - y - 1) + .5f) / float(height);
1792 const float z = (xf + yf) / 2.0f;
1793 const Vec3 fragCoord (float(x) + .5f, float(y) + .5f, z);
1794 const Vec3 scaledFC = fragCoord*scale;
1795 const Vec4 color (scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
1796 const Vec4 resultColor = getResultImage().getAccess().getPixel(x, y);
1797
1798 if (de::abs(color.x() - resultColor.x()) > precision ||
1799 de::abs(color.y() - resultColor.y()) > precision ||
1800 de::abs(color.z() - resultColor.z()) > precision)
1801 return TestStatus::fail("Image mismatch");
1802 }
1803 }
1804
1805 return TestStatus::pass("Result image matches reference");
1806 }
1807
setupDefaultInputs(void)1808 void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void)
1809 {
1810 const float vertices[] =
1811 {
1812 -1.0f, 1.0f, 0.0f, 1.0f,
1813 -1.0f, -1.0f, 0.5f, 1.0f,
1814 1.0f, 1.0f, 0.5f, 1.0f,
1815 1.0f, -1.0f, 1.0f, 1.0f,
1816 };
1817
1818 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
1819 }
1820
1821 class BuiltinGlFragCoordXYZCase : public TestCase
1822 {
1823 public:
1824 BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description);
1825 virtual ~BuiltinGlFragCoordXYZCase (void);
1826
1827 void initPrograms (SourceCollections& dst) const;
1828 TestInstance* createInstance (Context& context) const;
1829
1830 private:
1831 BuiltinGlFragCoordXYZCase (const BuiltinGlFragCoordXYZCase&); // not allowed!
1832 BuiltinGlFragCoordXYZCase& operator= (const BuiltinGlFragCoordXYZCase&); // not allowed!
1833 };
1834
BuiltinGlFragCoordXYZCase(TestContext & testCtx,const string & name,const string & description)1835 BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description)
1836 : TestCase(testCtx, name, description)
1837 {
1838 }
1839
~BuiltinGlFragCoordXYZCase(void)1840 BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void)
1841 {
1842 }
1843
initPrograms(SourceCollections & dst) const1844 void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const
1845 {
1846 dst.glslSources.add("vert") << glu::VertexSource(
1847 "#version 310 es\n"
1848 "layout(location = 0) in highp vec4 a_position;\n"
1849 "void main (void)\n"
1850 "{\n"
1851 " gl_Position = a_position;\n"
1852 "}\n");
1853
1854 dst.glslSources.add("frag") << glu::FragmentSource(
1855 "#version 310 es\n"
1856 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
1857 "layout(location = 0) out highp vec4 o_color;\n"
1858 "void main (void)\n"
1859 "{\n"
1860 " o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n"
1861 "}\n");
1862 }
1863
createInstance(Context & context) const1864 TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const
1865 {
1866 return new BuiltinGlFragCoordXYZCaseInstance(context);
1867 }
1868
projectedTriInterpolate(const Vec3 & s,const Vec3 & w,float nx,float ny)1869 inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny)
1870 {
1871 return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]);
1872 }
1873
1874 class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance
1875 {
1876 public:
1877 BuiltinGlFragCoordWCaseInstance (Context& context);
1878
1879 TestStatus iterate (void);
1880 virtual void setupDefaultInputs (void);
1881
1882 private:
1883
1884 const Vec4 m_w;
1885
1886 };
1887
BuiltinGlFragCoordWCaseInstance(Context & context)1888 BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context)
1889 : ShaderRenderCaseInstance (context)
1890 , m_w (1.7f, 2.0f, 1.2f, 1.0f)
1891 {
1892 m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM;
1893 }
1894
iterate(void)1895 TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void)
1896 {
1897 const UVec2 viewportSize = getViewportSize();
1898 const int width = viewportSize.x();
1899 const int height = viewportSize.y();
1900 const float precision = 0.00001f;
1901 const deUint16 indices[6] =
1902 {
1903 2, 1, 3,
1904 0, 1, 2,
1905 };
1906
1907 setup();
1908 render(4, 2, indices);
1909
1910 // Reference image
1911 for (int y = 0; y < height; y++)
1912 {
1913 for (int x = 0; x < width; x++)
1914 {
1915 const float xf = (float(x) + .5f) / float(width);
1916 const float yf = (float(height - y - 1) +.5f) / float(height);
1917 const float oow = ((xf + yf) < 1.0f)
1918 ? projectedTriInterpolate(Vec3(m_w[0], m_w[1], m_w[2]), Vec3(m_w[0], m_w[1], m_w[2]), xf, yf)
1919 : projectedTriInterpolate(Vec3(m_w[3], m_w[2], m_w[1]), Vec3(m_w[3], m_w[2], m_w[1]), 1.0f - xf, 1.0f - yf);
1920 const Vec4 color (0.0f, oow - 1.0f, 0.0f, 1.0f);
1921 const Vec4 resultColor = getResultImage().getAccess().getPixel(x, y);
1922
1923 if (de::abs(color.x() - resultColor.x()) > precision ||
1924 de::abs(color.y() - resultColor.y()) > precision ||
1925 de::abs(color.z() - resultColor.z()) > precision)
1926 return TestStatus::fail("Image mismatch");
1927 }
1928 }
1929
1930 return TestStatus::pass("Result image matches reference");
1931 }
1932
setupDefaultInputs(void)1933 void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void)
1934 {
1935 const float vertices[] =
1936 {
1937 -m_w[0], m_w[0], 0.0f, m_w[0],
1938 -m_w[1], -m_w[1], 0.0f, m_w[1],
1939 m_w[2], m_w[2], 0.0f, m_w[2],
1940 m_w[3], -m_w[3], 0.0f, m_w[3]
1941 };
1942
1943 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
1944 }
1945
1946 class BuiltinGlFragCoordWCase : public TestCase
1947 {
1948 public:
1949 BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description);
1950 virtual ~BuiltinGlFragCoordWCase (void);
1951
1952 void initPrograms (SourceCollections& dst) const;
1953 TestInstance* createInstance (Context& context) const;
1954
1955 private:
1956 BuiltinGlFragCoordWCase (const BuiltinGlFragCoordWCase&); // not allowed!
1957 BuiltinGlFragCoordWCase& operator= (const BuiltinGlFragCoordWCase&); // not allowed!
1958 };
1959
BuiltinGlFragCoordWCase(TestContext & testCtx,const string & name,const string & description)1960 BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description)
1961 : TestCase(testCtx, name, description)
1962 {
1963 }
1964
~BuiltinGlFragCoordWCase(void)1965 BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void)
1966 {
1967 }
1968
initPrograms(SourceCollections & dst) const1969 void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const
1970 {
1971 dst.glslSources.add("vert") << glu::VertexSource(
1972 "#version 310 es\n"
1973 "layout(location = 0) in highp vec4 a_position;\n"
1974 "void main (void)\n"
1975 "{\n"
1976 " gl_Position = a_position;\n"
1977 "}\n");
1978
1979 dst.glslSources.add("frag") << glu::FragmentSource(
1980 "#version 310 es\n"
1981 "layout(location = 0) out highp vec4 o_color;\n"
1982 "void main (void)\n"
1983 "{\n"
1984 " o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
1985 "}\n");
1986 }
1987
createInstance(Context & context) const1988 TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const
1989 {
1990 return new BuiltinGlFragCoordWCaseInstance(context);
1991 }
1992
1993 enum
1994 {
1995 POINTCOORD_VARIANT_DEFAULT,
1996 POINTCOORD_VARIANT_UNIFORM_VERTEX,
1997 POINTCOORD_VARIANT_UNIFORM_FRAGMENT
1998 };
1999
2000
2001 class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance
2002 {
2003 public:
2004 BuiltinGlPointCoordCaseInstance (Context& context, int testVariant);
2005
2006 TestStatus iterate (void);
2007 virtual void setupDefaultInputs (void);
2008 private:
2009 int variant;
2010 };
2011
BuiltinGlPointCoordCaseInstance(Context & context,int testVariant)2012 BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context, int testVariant)
2013 : ShaderRenderCaseInstance (context),
2014 variant(testVariant)
2015 {
2016 }
2017
iterate(void)2018 TestStatus BuiltinGlPointCoordCaseInstance::iterate (void)
2019 {
2020 const UVec2 viewportSize = getViewportSize();
2021 const int width = viewportSize.x();
2022 const int height = viewportSize.y();
2023 const float threshold = 0.02f;
2024 const int numPoints = 16;
2025 vector<Vec3> coords (numPoints);
2026 de::Random rnd (0x145fa);
2027 Surface resImage (width, height);
2028 Surface refImage (width, height);
2029 bool compareOk = false;
2030 const tcu::Vec3 scale(1.0f / float(width), 1.0f / float(height), 1.0f);
2031
2032 // Compute coordinates.
2033 {
2034 const VkPhysicalDeviceLimits& limits = m_context.getDeviceProperties().limits;
2035 const float minPointSize = limits.pointSizeRange[0];
2036 const float maxPointSize = limits.pointSizeRange[1];
2037 const int pointSizeDeltaMultiples = de::max(1, deCeilFloatToInt32((maxPointSize - minPointSize) / limits.pointSizeGranularity));
2038
2039 TCU_CHECK(minPointSize <= maxPointSize);
2040
2041 for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
2042 {
2043 coord->x() = rnd.getFloat(-0.9f, 0.9f);
2044 coord->y() = rnd.getFloat(-0.9f, 0.9f);
2045 coord->z() = de::min(maxPointSize, minPointSize + float(rnd.getInt(0, pointSizeDeltaMultiples)) * limits.pointSizeGranularity);
2046 }
2047 }
2048
2049 setup();
2050
2051 if (variant == POINTCOORD_VARIANT_UNIFORM_VERTEX || variant == POINTCOORD_VARIANT_UNIFORM_FRAGMENT)
2052 addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
2053
2054 addAttribute(0u, VK_FORMAT_R32G32B32_SFLOAT, deUint32(sizeof(Vec3)), numPoints, &coords[0]);
2055 render(numPoints, 0, DE_NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
2056 copy(resImage.getAccess(), getResultImage().getAccess());
2057
2058 // Draw reference
2059 clear(refImage.getAccess(), m_clearColor);
2060
2061 for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
2062 {
2063 float x = pointIter->x();
2064 float y = pointIter->y();
2065 if (variant == POINTCOORD_VARIANT_UNIFORM_VERTEX)
2066 {
2067 x *= scale.m_data[0];
2068 y *= scale.m_data[1];
2069 }
2070 const float centerX = float(width) *(x*0.5f + 0.5f);
2071 const float centerY = float(height)*(y*0.5f + 0.5f);
2072 const float size = pointIter->z();
2073 const int x0 = deRoundFloatToInt32(centerX - size*0.5f);
2074 const int y0 = deRoundFloatToInt32(centerY - size*0.5f);
2075 const int x1 = deRoundFloatToInt32(centerX + size*0.5f);
2076 const int y1 = deRoundFloatToInt32(centerY + size*0.5f);
2077 const int w = x1-x0;
2078 const int h = y1-y0;
2079
2080 for (int yo = 0; yo < h; yo++)
2081 {
2082 for (int xo = 0; xo < w; xo++)
2083 {
2084 const int dx = x0+xo;
2085 const int dy = y0+yo;
2086 const float fragX = float(dx) + 0.5f;
2087 const float fragY = float(dy) + 0.5f;
2088 const float s = 0.5f + (fragX - centerX) / size;
2089 const float t = 0.5f + (fragY - centerY) / size;
2090 Vec4 color (s, t, 0.0f, 1.0f);
2091
2092 if (variant == POINTCOORD_VARIANT_UNIFORM_FRAGMENT)
2093 {
2094 color.m_data[0] *= scale.m_data[0];
2095 color.m_data[1] *= scale.m_data[1];
2096 color.m_data[2] *= scale.m_data[2];
2097 }
2098
2099 if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight()))
2100 refImage.setPixel(dx, dy, RGBA(color));
2101 }
2102 }
2103 }
2104
2105 compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
2106
2107 if (compareOk)
2108 return TestStatus::pass("Result image matches reference");
2109 else
2110 return TestStatus::fail("Image mismatch");
2111 }
2112
setupDefaultInputs(void)2113 void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void)
2114 {
2115 }
2116
2117 class BuiltinGlPointCoordCase : public TestCase
2118 {
2119 public:
2120 BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description, int testVariant);
2121 virtual ~BuiltinGlPointCoordCase (void);
2122
2123 void initPrograms (SourceCollections& dst) const;
2124 TestInstance* createInstance (Context& context) const;
2125
2126 private:
2127 int variant;
2128 BuiltinGlPointCoordCase (const BuiltinGlPointCoordCase&); // not allowed!
2129 BuiltinGlPointCoordCase& operator= (const BuiltinGlPointCoordCase&); // not allowed!
2130 };
2131
BuiltinGlPointCoordCase(TestContext & testCtx,const string & name,const string & description,int testVariant)2132 BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description, int testVariant)
2133 : TestCase(testCtx, name, description),
2134 variant(testVariant)
2135 {
2136 }
2137
~BuiltinGlPointCoordCase(void)2138 BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void)
2139 {
2140 }
2141
initPrograms(SourceCollections & dst) const2142 void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const
2143 {
2144 switch (variant)
2145 {
2146 case POINTCOORD_VARIANT_UNIFORM_FRAGMENT:
2147 dst.glslSources.add("vert") << glu::VertexSource(
2148 "#version 310 es\n"
2149 "layout(location = 0) in highp vec3 a_position;\n"
2150 "void main (void)\n"
2151 "{\n"
2152 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
2153 " gl_PointSize = a_position.z;\n"
2154 "}\n");
2155
2156 dst.glslSources.add("frag") << glu::FragmentSource(
2157 "#version 310 es\n"
2158 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
2159 "layout(location = 0) out lowp vec4 o_color;\n"
2160 "void main (void)\n"
2161 "{\n"
2162 " o_color = vec4(gl_PointCoord, 0.0, 1.0) * vec4(u_scale, 1.0);\n"
2163 "}\n");
2164 break;
2165 case POINTCOORD_VARIANT_UNIFORM_VERTEX:
2166 dst.glslSources.add("vert") << glu::VertexSource(
2167 "#version 310 es\n"
2168 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
2169 "layout(location = 0) in highp vec3 a_position;\n"
2170 "void main (void)\n"
2171 "{\n"
2172 " gl_Position = vec4(a_position.xy, 0.0, 1.0) * vec4(u_scale, 1.0);\n"
2173 " gl_PointSize = a_position.z;\n"
2174 "}\n");
2175
2176 dst.glslSources.add("frag") << glu::FragmentSource(
2177 "#version 310 es\n"
2178 "layout(location = 0) out lowp vec4 o_color;\n"
2179 "void main (void)\n"
2180 "{\n"
2181 " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
2182 "}\n");
2183 break;
2184 default: // POINTCOORD_VARIANT_DEFAULT
2185 dst.glslSources.add("vert") << glu::VertexSource(
2186 "#version 310 es\n"
2187 "layout(location = 0) in highp vec3 a_position;\n"
2188 "void main (void)\n"
2189 "{\n"
2190 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
2191 " gl_PointSize = a_position.z;\n"
2192 "}\n");
2193
2194 dst.glslSources.add("frag") << glu::FragmentSource(
2195 "#version 310 es\n"
2196 "layout(location = 0) out lowp vec4 o_color;\n"
2197 "void main (void)\n"
2198 "{\n"
2199 " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
2200 "}\n");
2201 }
2202 }
2203
createInstance(Context & context) const2204 TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const
2205 {
2206 return new BuiltinGlPointCoordCaseInstance(context, variant);
2207 }
2208
2209 enum ShaderInputTypeBits
2210 {
2211 SHADER_INPUT_BUILTIN_BIT = 0x01,
2212 SHADER_INPUT_VARYING_BIT = 0x02,
2213 SHADER_INPUT_CONSTANT_BIT = 0x04
2214 };
2215
2216 typedef deUint16 ShaderInputTypes;
2217
shaderInputTypeToString(ShaderInputTypes type)2218 string shaderInputTypeToString (ShaderInputTypes type)
2219 {
2220 string typeString = "input";
2221
2222 if (type == 0)
2223 return "input_none";
2224
2225 if (type & SHADER_INPUT_BUILTIN_BIT)
2226 typeString += "_builtin";
2227
2228 if (type & SHADER_INPUT_VARYING_BIT)
2229 typeString += "_varying";
2230
2231 if (type & SHADER_INPUT_CONSTANT_BIT)
2232 typeString += "_constant";
2233
2234 return typeString;
2235 }
2236
2237 class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance
2238 {
2239 public:
2240 BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes);
2241
2242 TestStatus iterate (void);
2243 virtual void setupDefaultInputs (void);
2244 virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
2245
2246 private:
2247 const ShaderInputTypes m_shaderInputTypes;
2248 const Vec4 m_constantColor;
2249 };
2250
BuiltinInputVariationsCaseInstance(Context & context,const ShaderInputTypes shaderInputTypes)2251 BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes)
2252 : ShaderRenderCaseInstance (context)
2253 , m_shaderInputTypes (shaderInputTypes)
2254 , m_constantColor (0.1f, 0.05f, 0.2f, 0.0f)
2255 {
2256 }
2257
iterate(void)2258 TestStatus BuiltinInputVariationsCaseInstance::iterate (void)
2259 {
2260 const UVec2 viewportSize = getViewportSize();
2261 const int width = viewportSize.x();
2262 const int height = viewportSize.y();
2263 const tcu::RGBA threshold (2, 2, 2, 2);
2264 Surface resImage (width, height);
2265 Surface refImage (width, height);
2266 bool compareOk = false;
2267 const VkPushConstantRange pcRanges =
2268 {
2269 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
2270 0u, // deUint32 offset;
2271 sizeof(Vec4) // deUint32 size;
2272 };
2273 const deUint16 indices[12] =
2274 {
2275 0, 4, 1,
2276 0, 5, 4,
2277 1, 2, 3,
2278 1, 3, 4
2279 };
2280
2281 setup();
2282
2283 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2284 setPushConstantRanges(1, &pcRanges);
2285
2286 render(6, 4, indices);
2287 copy(resImage.getAccess(), getResultImage().getAccess());
2288
2289 // Reference image
2290 for (int y = 0; y < refImage.getHeight(); y++)
2291 {
2292 for (int x = 0; x < refImage.getWidth(); x++)
2293 {
2294 Vec4 color (0.1f, 0.2f, 0.3f, 1.0f);
2295
2296 if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) ||
2297 !(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT))
2298 {
2299 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
2300 {
2301 const float xf = (float(x)+.5f) / float(refImage.getWidth());
2302 color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f);
2303 }
2304 else
2305 color += Vec4(0.3f, 0.2f, 0.1f, 0.0f);
2306 }
2307
2308 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2309 color += m_constantColor;
2310
2311 refImage.setPixel(x, y, RGBA(color));
2312 }
2313 }
2314
2315 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
2316
2317 if (compareOk)
2318 return TestStatus::pass("Result image matches reference");
2319 else
2320 return TestStatus::fail("Image mismatch");
2321 }
2322
setupDefaultInputs(void)2323 void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void)
2324 {
2325 const float vertices[] =
2326 {
2327 -1.0f, -1.0f, 0.0f, 1.0f,
2328 0.0f, -1.0f, 0.0f, 1.0f,
2329 1.0f, -1.0f, 0.0f, 1.0f,
2330 1.0f, 1.0f, 0.0f, 1.0f,
2331 0.0f, 1.0f, 0.0f, 1.0f,
2332 -1.0f, 1.0f, 0.0f, 1.0f
2333 };
2334
2335 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
2336
2337 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
2338 {
2339 const float colors[] =
2340 {
2341 0.6f, 0.0f, 0.0f, 1.0f,
2342 0.3f, 0.3f, 0.0f, 1.0f,
2343 0.0f, 0.6f, 0.0f, 1.0f,
2344 0.0f, 0.6f, 0.0f, 1.0f,
2345 0.3f, 0.3f, 0.0f, 1.0f,
2346 0.6f, 0.0f, 0.0f, 1.0f
2347 };
2348 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors);
2349 }
2350 }
2351
updatePushConstants(vk::VkCommandBuffer commandBuffer,vk::VkPipelineLayout pipelineLayout)2352 void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout)
2353 {
2354 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2355 {
2356 const DeviceInterface& vk = m_context.getDeviceInterface();
2357 vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor);
2358 }
2359 }
2360
2361 class BuiltinInputVariationsCase : public TestCase
2362 {
2363 public:
2364 BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, const ShaderInputTypes shaderInputTypes);
2365 virtual ~BuiltinInputVariationsCase (void);
2366
2367 void initPrograms (SourceCollections& dst) const;
2368 TestInstance* createInstance (Context& context) const;
2369
2370 private:
2371 BuiltinInputVariationsCase (const BuiltinInputVariationsCase&); // not allowed!
2372 BuiltinInputVariationsCase& operator= (const BuiltinInputVariationsCase&); // not allowed!
2373 const ShaderInputTypes m_shaderInputTypes;
2374 };
2375
BuiltinInputVariationsCase(TestContext & testCtx,const string & name,const string & description,ShaderInputTypes shaderInputTypes)2376 BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, ShaderInputTypes shaderInputTypes)
2377 : TestCase (testCtx, name, description)
2378 , m_shaderInputTypes (shaderInputTypes)
2379 {
2380 }
2381
~BuiltinInputVariationsCase(void)2382 BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void)
2383 {
2384 }
2385
initPrograms(SourceCollections & dst) const2386 void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const
2387 {
2388 map<string, string> vertexParams;
2389 map<string, string> fragmentParams;
2390 const tcu::StringTemplate vertexCodeTemplate (
2391 "#version 450\n"
2392 "layout(location = 0) in highp vec4 a_position;\n"
2393 "out gl_PerVertex {\n"
2394 " vec4 gl_Position;\n"
2395 "};\n"
2396 "${VARYING_DECL}"
2397 "void main (void)\n"
2398 "{\n"
2399 " gl_Position = a_position;\n"
2400 " ${VARYING_USAGE}"
2401 "}\n");
2402
2403 const tcu::StringTemplate fragmentCodeTemplate (
2404 "#version 450\n"
2405 "${VARYING_DECL}"
2406 "${CONSTANT_DECL}"
2407 "layout(location = 0) out highp vec4 o_color;\n"
2408 "void main (void)\n"
2409 "{\n"
2410 " o_color = vec4(0.1, 0.2, 0.3, 1.0);\n"
2411 " ${BUILTIN_USAGE}"
2412 " ${VARYING_USAGE}"
2413 " ${CONSTANT_USAGE}"
2414 "}\n");
2415
2416 vertexParams["VARYING_DECL"] =
2417 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 1) in highp vec4 a_color;\n"
2418 "layout(location = 0) out highp vec4 v_color;\n"
2419 : "";
2420
2421 vertexParams["VARYING_USAGE"] =
2422 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "v_color = a_color;\n"
2423 : "";
2424
2425 fragmentParams["VARYING_DECL"] =
2426 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 0) in highp vec4 a_color;\n"
2427 : "";
2428
2429 fragmentParams["CONSTANT_DECL"] =
2430 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "layout(push_constant) uniform PCBlock {\n"
2431 " vec4 color;\n"
2432 "} pc;\n"
2433 : "";
2434
2435 fragmentParams["BUILTIN_USAGE"] =
2436 m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT ? "if (gl_FrontFacing)\n"
2437 : "";
2438
2439 fragmentParams["VARYING_USAGE"] =
2440 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "o_color += vec4(a_color.xyz, 0.0);\n"
2441 : "o_color += vec4(0.3, 0.2, 0.1, 0.0);\n";
2442
2443
2444 fragmentParams["CONSTANT_USAGE"] =
2445 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "o_color += pc.color;\n"
2446 : "";
2447
2448 dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams));
2449 dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams));
2450 }
2451
createInstance(Context & context) const2452 TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const
2453 {
2454 return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes);
2455 }
2456
2457 } // anonymous
2458
createBuiltinVarTests(TestContext & testCtx)2459 TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
2460 {
2461 de::MovePtr<TestCaseGroup> builtinGroup (new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
2462 de::MovePtr<TestCaseGroup> simpleGroup (new TestCaseGroup(testCtx, "simple", "Simple cases."));
2463 de::MovePtr<TestCaseGroup> inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests."));
2464 de::MovePtr<TestCaseGroup> frontFacingGroup (new TestCaseGroup(testCtx, "frontfacing", "Test gl_Frontfacing keyword."));
2465 de::MovePtr<TestCaseGroup> fragDepthGroup (new TestCaseGroup(testCtx, "fragdepth", "Test gl_FragDepth keyword."));
2466 de::MovePtr<TestCaseGroup> fragCoordMsaaGroup (new TestCaseGroup(testCtx, "fragcoord_msaa", "Test interation between gl_FragCoord and msaa"));
2467 de::MovePtr<TestCaseGroup> fragCoordMsaaInputGroup (new TestCaseGroup(testCtx, "fragcoord_msaa_input", "Test interation between gl_FragCoord and msaa"));
2468
2469 simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test"));
2470 simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test"));
2471 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", "PointCoord test", POINTCOORD_VARIANT_DEFAULT));
2472 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord_uniform_frag", "PointCoord test with fragment uniform", POINTCOORD_VARIANT_UNIFORM_FRAGMENT));
2473 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord_uniform_vert", "PointCoord test with vertex uniform", POINTCOORD_VARIANT_UNIFORM_VERTEX));
2474
2475 // FragCoord_msaa
2476 {
2477 static const struct FragCoordMsaaCaseList
2478 {
2479 const char* name;
2480 const char* description;
2481 VkSampleCountFlagBits sampleCount;
2482 } fragCoordMsaaCaseList[] =
2483 {
2484 { "1_bit", "Test FragCoord locations with 1 sample", VK_SAMPLE_COUNT_1_BIT },
2485 { "2_bit", "Test FragCoord locations with 2 samples", VK_SAMPLE_COUNT_2_BIT },
2486 { "4_bit", "Test FragCoord locations with 4 samples", VK_SAMPLE_COUNT_4_BIT },
2487 { "8_bit", "Test FragCoord locations with 8 samples", VK_SAMPLE_COUNT_8_BIT },
2488 { "16_bit", "Test FragCoord locations with 16 samples", VK_SAMPLE_COUNT_16_BIT },
2489 { "32_bit", "Test FragCoord locations with 32 samples", VK_SAMPLE_COUNT_32_BIT },
2490 { "64_bit", "Test FragCoord locaitons with 64 samples", VK_SAMPLE_COUNT_64_BIT },
2491 };
2492
2493 // Standard sample tests
2494 std::vector<uint32_t> sampleMaskArray;
2495
2496 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2497 {
2498 fragCoordMsaaGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, true, sampleMaskArray, false, true));
2499 fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, true, sampleMaskArray, false, false));
2500 }
2501
2502 sampleMaskArray.push_back(1u);
2503
2504 // No sample shading tests
2505 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2506 {
2507 fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, (std::string(fragCoordMsaaCaseList[caseNdx].name) + "_no_sample_shading").c_str(), fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, false, sampleMaskArray, false, false));
2508 }
2509
2510 // No sample shading tests with centroid interpolation decoration
2511 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2512 {
2513 fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, (std::string(fragCoordMsaaCaseList[caseNdx].name) + "_no_sample_shading_centroid_interpolation").c_str(), fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, false, sampleMaskArray, true, false));
2514 }
2515 }
2516
2517 // gl_FrontFacing tests
2518 {
2519 static const struct PrimitiveTable
2520 {
2521 const char* name;
2522 const char* desc;
2523 VkPrimitiveTopology primitive;
2524 } frontfacingCases[] =
2525 {
2526 { "point_list", "Test that points are frontfacing", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
2527 { "line_list", "Test that lines are frontfacing", VK_PRIMITIVE_TOPOLOGY_LINE_LIST },
2528 { "triangle_list", "Test that triangles can be frontfacing or backfacing", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST },
2529 { "triangle_strip", "Test that traiangle strips can be front or back facing", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
2530 { "triangle_fan", "Test that triangle fans can be front or back facing", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN },
2531 };
2532
2533 for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(frontfacingCases); ndx++)
2534 frontFacingGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, frontfacingCases[ndx].primitive, frontfacingCases[ndx].name, frontfacingCases[ndx].desc));
2535 }
2536
2537 // gl_FragDepth
2538 {
2539 static const struct PrimitiveTopologyTable
2540 {
2541 std::string name;
2542 std::string desc;
2543 VkPrimitiveTopology prim;
2544 } primitiveTopologyTable[] =
2545 {
2546 { "point_list", "test that points respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
2547 { "line_list", "test taht lines respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_LINE_LIST },
2548 { "triangle_list", "test that triangles respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
2549 };
2550
2551 static const struct TestCaseTable
2552 {
2553 VkFormat format;
2554 std::string name;
2555 bool largeDepthEnable;
2556 bool depthClampEnable;
2557 VkSampleCountFlagBits samples;
2558 } testCaseTable[] =
2559 {
2560 { VK_FORMAT_D16_UNORM, "d16_unorm_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2561 { VK_FORMAT_X8_D24_UNORM_PACK32, "x8_d24_unorm_pack32_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2562 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2563 { VK_FORMAT_D16_UNORM_S8_UINT, "d16_unorm_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2564 { VK_FORMAT_D24_UNORM_S8_UINT, "d24_unorm_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2565 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2566 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_large_depth", true, false, VK_SAMPLE_COUNT_1_BIT },
2567 { VK_FORMAT_D32_SFLOAT, "d32_sfloat", false, true, VK_SAMPLE_COUNT_1_BIT },
2568 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint", false, true, VK_SAMPLE_COUNT_1_BIT },
2569 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_2", false, false, VK_SAMPLE_COUNT_2_BIT },
2570 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_4", false, false, VK_SAMPLE_COUNT_4_BIT },
2571 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_8", false, false, VK_SAMPLE_COUNT_8_BIT },
2572 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_16", false, false, VK_SAMPLE_COUNT_16_BIT },
2573 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_32", false, false, VK_SAMPLE_COUNT_32_BIT },
2574 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_64", false, false, VK_SAMPLE_COUNT_64_BIT },
2575 };
2576
2577 for (deUint32 primNdx = 0; primNdx < DE_LENGTH_OF_ARRAY(primitiveTopologyTable); primNdx++)
2578 {
2579 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(testCaseTable); caseNdx++)
2580 fragDepthGroup->addChild(new BuiltinFragDepthCase(testCtx, (primitiveTopologyTable[primNdx].name+"_" + testCaseTable[caseNdx].name).c_str(), primitiveTopologyTable[primNdx].desc.c_str(),
2581 primitiveTopologyTable[primNdx].prim, testCaseTable[caseNdx].format, testCaseTable[caseNdx].largeDepthEnable, testCaseTable[caseNdx].depthClampEnable, testCaseTable[caseNdx].samples));
2582
2583 }
2584 }
2585
2586 builtinGroup->addChild(frontFacingGroup.release());
2587 builtinGroup->addChild(fragDepthGroup.release());
2588 builtinGroup->addChild(fragCoordMsaaGroup.release());
2589 builtinGroup->addChild(fragCoordMsaaInputGroup.release());
2590 builtinGroup->addChild(simpleGroup.release());
2591
2592 for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType)
2593 {
2594 inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), "Input variation test", shaderType));
2595 }
2596
2597 builtinGroup->addChild(inputVariationsGroup.release());
2598 return builtinGroup.release();
2599 }
2600
2601 } // sr
2602 } // vkt
2603