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