Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / draw / vktDrawDiscardRectanglesTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 Valve Corporation.
6  * Copyright (c) 2019 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief EXT_discard_rectangles tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktDrawDiscardRectanglesTests.hpp"
26
27 #include "vkDefs.hpp"
28 #include "vkRef.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkTypeUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vktTestGroupUtil.hpp"
37 #include "vktTestCase.hpp"
38 #include "vktDrawBufferObjectUtil.hpp"
39 #include "vktDrawImageObjectUtil.hpp"
40
41 #include "tcuTestCase.hpp"
42 #include "tcuVector.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuImageCompare.hpp"
46
47 #include "deUniquePtr.hpp"
48 #include "deSharedPtr.hpp"
49
50 namespace vkt
51 {
52 namespace Draw
53 {
54
55 namespace
56 {
57 using namespace vk;
58 using de::UniquePtr;
59 using de::SharedPtr;
60 using de::MovePtr;
61 using tcu::Vec4;
62 using tcu::Vec2;
63 using tcu::UVec2;
64 using tcu::UVec4;
65
66 enum TestMode
67 {
68         TEST_MODE_INCLUSIVE = 0,
69         TEST_MODE_EXCLUSIVE,
70         TEST_MODE_COUNT
71 };
72
73 enum TestScissorMode
74 {
75         TEST_SCISSOR_MODE_NONE = 0,
76         TEST_SCISSOR_MODE_STATIC,
77         TEST_SCISSOR_MODE_DYNAMIC,
78         TEST_SCISSOR_MODE_COUNT
79 };
80
81 #define NUM_RECT_TESTS 6
82 #define NUM_DYNAMIC_DISCARD_TYPE_TESTS 2
83
84 struct TestParams
85 {
86         TestMode                                testMode;
87         deUint32                                numRectangles;
88         deBool                                  dynamicDiscardRectangles;
89         TestScissorMode                 scissorMode;
90         const SharedGroupParams groupParams;
91 };
92
93 template<typename T>
94 inline VkDeviceSize sizeInBytes(const std::vector<T>& vec)
95 {
96         return vec.size() * sizeof(vec[0]);
97 }
98
99 VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const UVec2& size, VkImageUsageFlags usage)
100 {
101         const VkImageCreateInfo imageParams =
102         {
103                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
104                 DE_NULL,                                                                                // const void*                          pNext;
105                 (VkImageCreateFlags)0,                                                  // VkImageCreateFlags           flags;
106                 VK_IMAGE_TYPE_2D,                                                               // VkImageType                          imageType;
107                 format,                                                                                 // VkFormat                                     format;
108                 makeExtent3D(size.x(), size.y(), 1),                    // VkExtent3D                           extent;
109                 1u,                                                                                             // deUint32                                     mipLevels;
110                 1u,                                                                                             // deUint32                                     arrayLayers;
111                 VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples;
112                 VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
113                 usage,                                                                                  // VkImageUsageFlags            usage;
114                 VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
115                 0u,                                                                                             // deUint32                                     queueFamilyIndexCount;
116                 DE_NULL,                                                                                // const deUint32*                      pQueueFamilyIndices;
117                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        initialLayout;
118         };
119         return imageParams;
120 }
121
122 VkPipelineDiscardRectangleStateCreateInfoEXT makeDiscardRectangleStateCreateInfo (const deBool                                          dynamicDiscardRectangle,
123                                                                                                                                                                   const VkDiscardRectangleModeEXT       discardRectangleMode,
124                                                                                                                                                                   const deUint32                                        discardRectangleCount,
125                                                                                                                                                                   const VkRect2D                                        *pDiscardRectangles)
126 {
127         const VkPipelineDiscardRectangleStateCreateInfoEXT discardRectanglesCreateInfo =
128         {
129                 VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT,             // VkStructureType                                                                      sType;
130                 DE_NULL,                                                                                                                                // const void*                                                                          pNext;
131                 0u,                                                                                                                                             // VkPipelineDiscardRectangleStateCreateFlagsEXT        flags;
132                 discardRectangleMode,                                                                                                   // VkDiscardRectangleModeEXT                                            discardRectangleMode;
133                 discardRectangleCount,                                                                                                  // deUint32                                                                                     discardRectangleCount;
134                 dynamicDiscardRectangle ? DE_NULL : pDiscardRectangles                                  // const VkRect2D*                                                                      pDiscardRectangles;
135         };
136         return discardRectanglesCreateInfo;
137 }
138
139 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&                   vk,
140                                                                            const VkDevice                                       device,
141                                                                            const VkPipelineLayout                       pipelineLayout,
142                                                                            const VkRenderPass                           renderPass,
143                                                                            const VkShaderModule                         vertexModule,
144                                                                            const VkShaderModule                         fragmentModule,
145                                                                            const UVec2                                          renderSize,
146                                                                            const deBool                                         dynamicDiscardRectangle,
147                                                                            const VkDiscardRectangleModeEXT      discardRectangleMode,
148                                                                            const deUint32                                       discardRectangleCount,
149                                                                            const VkRect2D*                                      pDiscardRectangles,
150                                                                            const TestScissorMode                        scissorMode,
151                                                                            const VkRect2D                                       rectScissor)
152 {
153         const VkVertexInputBindingDescription vertexInputBindingDescription =
154         {
155                 0u,                                                             // uint32_t                             binding;
156                 sizeof(Vec4),                                   // uint32_t                             stride;
157                 VK_VERTEX_INPUT_RATE_VERTEX,    // VkVertexInputRate    inputRate;
158         };
159
160         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
161         {
162                 {
163                         0u,                                                             // uint32_t                     location;
164                         0u,                                                             // uint32_t                     binding;
165                         VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat                     format;
166                         0u,                                                             // uint32_t                     offset;
167                 },
168         };
169
170         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
171         {
172                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                              sType;
173                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
174                 (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags                flags;
175                 1u,                                                                                                                             // uint32_t                                                                             vertexBindingDescriptionCount;
176                 &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*               pVertexBindingDescriptions;
177                 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),                   // uint32_t                                                                             vertexAttributeDescriptionCount;
178                 vertexInputAttributeDescriptions,                                                               // const VkVertexInputAttributeDescription*             pVertexAttributeDescriptions;
179         };
180
181         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
182         {
183                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                              sType;
184                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
185                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags              flags;
186                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,                                                   // VkPrimitiveTopology                                                  topology;
187                 VK_FALSE,                                                                                                               // VkBool32                                                                             primitiveRestartEnable;
188         };
189
190
191         VkViewport              viewport                                = makeViewport(0.0f, 0.0f, static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()), 0.0f, 1.0f);
192         const VkRect2D  rectScissorRenderSize   = { { 0, 0 }, { renderSize.x(), renderSize.y() } };
193
194         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
195         {
196                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                                                  // VkStructureType                                                              sType;
197                 DE_NULL,                                                                                                                                                // const void*                                                                  pNext;
198                 (VkPipelineViewportStateCreateFlags)0,                                                                                  // VkPipelineViewportStateCreateFlags                   flags;
199                 1u,                                                                                                                                                             // uint32_t                                                                             viewportCount;
200                 &viewport,                                                                                                                                              // const VkViewport*                                                    pViewports;
201                 1u,                                                                                                                                                             // uint32_t                                                                             scissorCount;
202                 scissorMode != TEST_SCISSOR_MODE_NONE ? &rectScissor : &rectScissorRenderSize,  // const VkRect2D*                                                              pScissors;
203         };
204
205         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
206         {
207                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                              sType;
208                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
209                 (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags              flags;
210                 VK_FALSE,                                                                                                               // VkBool32                                                                             depthClampEnable;
211                 VK_FALSE,                                                                                                               // VkBool32                                                                             rasterizerDiscardEnable;
212                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                                polygonMode;
213                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                              cullMode;
214                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                                  frontFace;
215                 VK_FALSE,                                                                                                               // VkBool32                                                                             depthBiasEnable;
216                 0.0f,                                                                                                                   // float                                                                                depthBiasConstantFactor;
217                 0.0f,                                                                                                                   // float                                                                                depthBiasClamp;
218                 0.0f,                                                                                                                   // float                                                                                depthBiasSlopeFactor;
219                 1.0f,                                                                                                                   // float                                                                                lineWidth;
220         };
221
222         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
223         {
224                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                              sType;
225                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
226                 (VkPipelineMultisampleStateCreateFlags)0,                                               // VkPipelineMultisampleStateCreateFlags                flags;
227                 VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits                                                rasterizationSamples;
228                 VK_FALSE,                                                                                                               // VkBool32                                                                             sampleShadingEnable;
229                 0.0f,                                                                                                                   // float                                                                                minSampleShading;
230                 DE_NULL,                                                                                                                // const VkSampleMask*                                                  pSampleMask;
231                 VK_FALSE,                                                                                                               // VkBool32                                                                             alphaToCoverageEnable;
232                 VK_FALSE                                                                                                                // VkBool32                                                                             alphaToOneEnable;
233         };
234
235         const VkStencilOpState stencilOpState = makeStencilOpState(
236                 VK_STENCIL_OP_KEEP,                             // stencil fail
237                 VK_STENCIL_OP_KEEP,                             // depth & stencil pass
238                 VK_STENCIL_OP_KEEP,                             // depth only fail
239                 VK_COMPARE_OP_ALWAYS,                   // compare op
240                 0u,                                                             // compare mask
241                 0u,                                                             // write mask
242                 0u);                                                    // reference
243
244         VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
245         {
246                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,             // VkStructureType                                                              sType;
247                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
248                 (VkPipelineDepthStencilStateCreateFlags)0,                                              // VkPipelineDepthStencilStateCreateFlags               flags;
249                 VK_FALSE,                                                                                                               // VkBool32                                                                             depthTestEnable;
250                 VK_FALSE,                                                                                                               // VkBool32                                                                             depthWriteEnable;
251                 VK_COMPARE_OP_LESS,                                                                                             // VkCompareOp                                                                  depthCompareOp;
252                 VK_FALSE,                                                                                                               // VkBool32                                                                             depthBoundsTestEnable;
253                 VK_FALSE,                                                                                                               // VkBool32                                                                             stencilTestEnable;
254                 stencilOpState,                                                                                                 // VkStencilOpState                                                             front;
255                 stencilOpState,                                                                                                 // VkStencilOpState                                                             back;
256                 0.0f,                                                                                                                   // float                                                                                minDepthBounds;
257                 1.0f,                                                                                                                   // float                                                                                maxDepthBounds;
258         };
259
260         const VkColorComponentFlags                                     colorComponentsAll                                      = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
261         const VkPipelineColorBlendAttachmentState       pipelineColorBlendAttachmentState       =
262         {
263                 VK_FALSE,                                               // VkBool32                                     blendEnable;
264                 VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcColorBlendFactor;
265                 VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        dstColorBlendFactor;
266                 VK_BLEND_OP_ADD,                                // VkBlendOp                            colorBlendOp;
267                 VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcAlphaBlendFactor;
268                 VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        dstAlphaBlendFactor;
269                 VK_BLEND_OP_ADD,                                // VkBlendOp                            alphaBlendOp;
270                 colorComponentsAll,                             // VkColorComponentFlags        colorWriteMask;
271         };
272
273         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
274         {
275                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,               // VkStructureType                                                              sType;
276                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
277                 (VkPipelineColorBlendStateCreateFlags)0,                                                // VkPipelineColorBlendStateCreateFlags                 flags;
278                 VK_FALSE,                                                                                                               // VkBool32                                                                             logicOpEnable;
279                 VK_LOGIC_OP_COPY,                                                                                               // VkLogicOp                                                                    logicOp;
280                 1u,                                                                                                                             // deUint32                                                                             attachmentCount;
281                 &pipelineColorBlendAttachmentState,                                                             // const VkPipelineColorBlendAttachmentState*   pAttachments;
282                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                             // float                                                                                blendConstants[4];
283         };
284
285         const VkPipelineShaderStageCreateInfo pShaderStages[] =
286         {
287                 {
288                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                                              sType;
289                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
290                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags                             flags;
291                         VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                                stage;
292                         vertexModule,                                                                                           // VkShaderModule                                                               module;
293                         "main",                                                                                                         // const char*                                                                  pName;
294                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                                  pSpecializationInfo;
295                 },
296                 {
297                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                                              sType;
298                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
299                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags                             flags;
300                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                                stage;
301                         fragmentModule,                                                                                         // VkShaderModule                                                               module;
302                         "main",                                                                                                         // const char*                                                                  pName;
303                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                                  pSpecializationInfo;
304                 },
305         };
306
307         const VkPipelineDiscardRectangleStateCreateInfoEXT discardRectangleStateCreateInfo = makeDiscardRectangleStateCreateInfo(dynamicDiscardRectangle, discardRectangleMode, discardRectangleCount, pDiscardRectangles);
308
309         const VkDynamicState dynamicStateDiscardRectangles      = VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT;
310         const VkDynamicState dynamicStateScissor                        = VK_DYNAMIC_STATE_SCISSOR;
311         std::vector<VkDynamicState> dynamicStates;
312
313         if (dynamicDiscardRectangle)
314                 dynamicStates.push_back(dynamicStateDiscardRectangles);
315         if (scissorMode == TEST_SCISSOR_MODE_DYNAMIC)
316                 dynamicStates.push_back(dynamicStateScissor);
317
318         const VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo =
319         {
320                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,                   // VkStructureType                                                              sType;
321                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
322                 0u,                                                                                                                             // VkPipelineDynamicStateCreateFlags                    flags;
323                 (deUint32)dynamicStates.size(),                                                                 // deUint32                                                                             dynamicStateCount;
324                 dynamicStates.data()                                                                                    // const VkDynamicState*                                                pDynamicStates;
325         };
326
327         VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
328         {
329                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                // VkStructureType                                                                      sType;
330                 &discardRectangleStateCreateInfo,                                                               // const void*                                                                          pNext;
331                 (VkPipelineCreateFlags)0,                                                                               // VkPipelineCreateFlags                                                        flags;
332                 2u,                                                                                                                             // deUint32                                                                                     stageCount;
333                 pShaderStages,                                                                                                  // const VkPipelineShaderStageCreateInfo*                       pStages;
334                 &vertexInputStateInfo,                                                                                  // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
335                 &pipelineInputAssemblyStateInfo,                                                                // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
336                 DE_NULL,                                                                                                                // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
337                 &pipelineViewportStateInfo,                                                                             // const VkPipelineViewportStateCreateInfo*                     pViewportState;
338                 &pipelineRasterizationStateInfo,                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
339                 &pipelineMultisampleStateInfo,                                                                  // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
340                 &pipelineDepthStencilStateInfo,                                                                 // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
341                 &pipelineColorBlendStateInfo,                                                                   // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
342                 &pipelineDynamicStateCreateInfo,                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
343                 pipelineLayout,                                                                                                 // VkPipelineLayout                                                                     layout;
344                 renderPass,                                                                                                             // VkRenderPass                                                                         renderPass;
345                 0u,                                                                                                                             // deUint32                                                                                     subpass;
346                 DE_NULL,                                                                                                                // VkPipeline                                                                           basePipelineHandle;
347                 0,                                                                                                                              // deInt32                                                                                      basePipelineIndex;
348         };
349
350 #ifndef CTS_USES_VULKANSC
351         VkFormat colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM;
352         vk::VkPipelineRenderingCreateInfoKHR renderingCreateInfo
353         {
354                 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
355                 &discardRectangleStateCreateInfo,
356                 0u,
357                 1u,
358                 &colorAttachmentFormat,
359                 VK_FORMAT_UNDEFINED,
360                 VK_FORMAT_UNDEFINED
361         };
362
363         // when pipeline is created without render pass we are using dynamic rendering
364         if (renderPass == DE_NULL)
365                 graphicsPipelineInfo.pNext = &renderingCreateInfo;
366 #endif // CTS_USES_VULKANSC
367
368         return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
369 }
370
371 void generateDiscardRectangles(const UVec2& renderSize, deUint32 numRect, std::vector<VkRect2D>& rectangles)
372 {
373         deUint32 cellHight = renderSize.y() - 10;
374         deUint32 cellWidth = (renderSize.x() - 10) / (2 * numRect - 1);
375
376         DE_ASSERT(rectangles.size() == 0);
377
378         for (deUint32 i = 0; i < numRect; i++)
379         {
380                 VkRect2D rect;
381                 rect.extent.height = cellHight;
382                 rect.extent.width = cellWidth;
383                 rect.offset.x = 5u + i * 2 * cellWidth;
384                 rect.offset.y = 5u;
385                 rectangles.push_back(rect);
386         }
387 }
388
389 //! Renders a colorful grid of rectangles.
390 tcu::TextureLevel generateReferenceImage (const tcu::TextureFormat              format,
391                                                                                   const UVec2&                                  renderSize,
392                                                                                   const TestMode                                testMode,
393                                                                                   const Vec4&                                   color,
394                                                                                   const deUint32                                numRectangles,
395                                                                                   const std::vector<VkRect2D>   rectangles,
396                                                                                   const deBool                                  enableScissor,
397                                                                                   const VkRect2D                                scissor)
398 {
399         tcu::TextureLevel       image(format, renderSize.x(), renderSize.y());
400         const Vec4                      rectColor       = testMode == TEST_MODE_INCLUSIVE ? Vec4(0.0f, 1.0f, 0.0f, 1.0f)        : color;
401         const Vec4                      clearColor      = testMode == TEST_MODE_INCLUSIVE ? color                                                       : Vec4(0.0f, 1.0f, 0.0f, 1.0f);
402
403         if (!enableScissor)
404         {
405                 // Clear the image with clearColor
406                 tcu::clear(image.getAccess(), clearColor);
407
408                 // Now draw the discard rectangles taking into account the selected mode.
409                 for (deUint32 i = 0; i < numRectangles; i++)
410                 {
411                         tcu::clear(tcu::getSubregion(image.getAccess(), rectangles[i].offset.x, rectangles[i].offset.y,
412                                                                                  rectangles[i].extent.width, rectangles[i].extent.height),
413                                            rectColor);
414                 }
415         }
416         else
417         {
418                 // Clear the image with the original clear color
419                 tcu::clear(image.getAccess(), color);
420                 // Clear the scissor are with the clearColor which depends on the selected mode
421                 tcu::clear(tcu::getSubregion(image.getAccess(), scissor.offset.x, scissor.offset.y,
422                                                                          scissor.extent.width, scissor.extent.height),
423                                    clearColor);
424
425                 // Now draw the discard rectangles taking into account both the scissor area and
426                 // the selected mode.
427                 for (deUint32 rect = 0; rect < numRectangles; rect++)
428                 {
429                         for (deUint32 x = rectangles[rect].offset.x; x < (rectangles[rect].offset.x + rectangles[rect].extent.width); x++)
430                         {
431                                 for(deUint32 y = rectangles[rect].offset.y; y < (rectangles[rect].offset.y + rectangles[rect].extent.height); y++)
432                                 {
433                                         if ((x >= (deUint32)scissor.offset.x) && (x < (scissor.offset.x + scissor.extent.width)) &&
434                                                 (y >= (deUint32)scissor.offset.y) && (y < (scissor.offset.y + scissor.extent.height)))
435                                         {
436                                                 image.getAccess().setPixel(rectColor, x, y);
437                                         }
438                                 }
439                         }
440                 }
441         }
442         return image;
443 }
444
445 class DiscardRectanglesTestInstance : public TestInstance
446 {
447 public:
448                                                         DiscardRectanglesTestInstance           (Context& context,
449                                                                                                                                  TestParams params);
450         virtual                                 ~DiscardRectanglesTestInstance          (void) {}
451         virtual tcu::TestStatus iterate                                                         (void);
452
453 protected:
454
455         void                                    preRenderCommands                                       (VkCommandBuffer cmdBuffer) const;
456         void                                    drawCommands                                            (VkCommandBuffer cmdBuffer, const VkRect2D& rectScissor) const;
457
458 #ifndef CTS_USES_VULKANSC
459         void                                    beginSecondaryCmdBuffer                         (VkCommandBuffer cmdBuffer, VkFormat colorFormat, VkRenderingFlagsKHR renderingFlags = 0u) const;
460 #endif // CTS_USES_VULKANSC
461
462 private:
463         const TestParams                        m_params;
464         const Vec4                                      m_clearColor;
465         const UVec2                                     m_renderSize;
466         std::vector<Vec4>                       m_vertices;
467         std::vector<VkRect2D>           m_rectangles;
468
469         Move<VkImage>                           m_colorImage;
470         MovePtr<Allocation>                     m_colorImageAlloc;
471         Move<VkImageView>                       m_colorAttachment;
472         SharedPtr<Buffer>                       m_colorBuffer;
473         SharedPtr<Buffer>                       m_vertexBuffer;
474         Move<VkShaderModule>            m_vertexModule;
475         Move<VkShaderModule>            m_fragmentModule;
476         Move<VkRenderPass>                      m_renderPass;
477         Move<VkFramebuffer>                     m_framebuffer;
478         Move<VkPipelineLayout>          m_pipelineLayout;
479         Move<VkPipeline>                        m_pipeline;
480         Move<VkCommandPool>                     m_cmdPool;
481         Move<VkCommandBuffer>           m_cmdBuffer;
482         Move<VkCommandBuffer>           m_secCmdBuffer;
483 };
484
485 DiscardRectanglesTestInstance::DiscardRectanglesTestInstance (Context& context,
486                                                                                                                           TestParams params)
487         : TestInstance  (context)
488         , m_params              (params)
489         , m_clearColor  (Vec4(1.0f, 0.0f, 0.0f, 1.0f))
490         , m_renderSize  (UVec2(340, 100))
491 {
492 }
493
494 tcu::TestStatus DiscardRectanglesTestInstance::iterate  (void)
495 {
496         const DeviceInterface&                  vk                                              = m_context.getDeviceInterface();
497         const InstanceInterface&                vki                                             = m_context.getInstanceInterface();
498         const VkPhysicalDevice                  physicalDevice                  = m_context.getPhysicalDevice();
499         const VkDevice                                  device                                  = m_context.getDevice();
500         const VkQueue                                   queue                                   = m_context.getUniversalQueue();
501         const deUint32                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
502         Allocator&                                              allocator                               = m_context.getDefaultAllocator();
503         const VkDiscardRectangleModeEXT discardRectangleMode    = m_params.testMode == TEST_MODE_EXCLUSIVE ? VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT : VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT;
504         const VkRect2D                                  rectScissor                             = { { 90, 25 }, { 160, 50} };
505         const VkImageSubresourceRange   colorSubresourceRange   = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
506         const VkFormat                                  colorFormat                             = VK_FORMAT_R8G8B8A8_UNORM;
507         const VkDeviceSize                              colorBufferSize                 = m_renderSize.x() * m_renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
508
509         // Check for VK_EXT_discard_rectangles support and maximum number of active discard rectangles
510         {
511                 VkPhysicalDeviceDiscardRectanglePropertiesEXT discardRectangleProperties;
512                 deMemset(&discardRectangleProperties, 0, sizeof(VkPhysicalDeviceDiscardRectanglePropertiesEXT));
513                 discardRectangleProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT;
514
515                 VkPhysicalDeviceProperties2 physicalDeviceProperties;
516                 physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
517                 physicalDeviceProperties.pNext = &discardRectangleProperties;
518
519                 vki.getPhysicalDeviceProperties2(physicalDevice, &physicalDeviceProperties);
520
521                 if (discardRectangleProperties.maxDiscardRectangles == 0)
522                 {
523                         throw tcu::NotSupportedError("Implementation doesn't support discard rectangles");
524                 }
525
526                 if (discardRectangleProperties.maxDiscardRectangles < 4)
527                 {
528                         std::ostringstream message;
529                         message << "Implementation doesn't support the minimum value for maxDiscardRectangles: " << discardRectangleProperties.maxDiscardRectangles << " < 4";
530                         return tcu::TestStatus::fail(message.str());
531                 }
532
533                 if (discardRectangleProperties.maxDiscardRectangles < m_params.numRectangles)
534                 {
535                         std::ostringstream message;
536                         message << "Implementation doesn't support the required number of discard rectangles: " << discardRectangleProperties.maxDiscardRectangles << " < " << m_params.numRectangles;
537                         throw tcu::NotSupportedError(message.str());
538                 }
539         }
540
541         // Color attachment
542         {
543                 m_colorImage            = makeImage(vk, device, makeImageCreateInfo(colorFormat, m_renderSize, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT));
544                 m_colorImageAlloc       = bindImage(vk, device, allocator, *m_colorImage, MemoryRequirement::Any);
545                 m_colorBuffer           = Buffer::createAndAlloc(vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), allocator, MemoryRequirement::HostVisible);
546                 m_colorAttachment       = makeImageView(vk, device, *m_colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange);
547
548                 // Zero colorBuffer.
549                 const Allocation alloc = m_colorBuffer->getBoundMemory();
550                 deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
551                 flushAlloc(vk, device, alloc);
552         }
553
554         // Initialize the pipeline and other variables
555         {
556                 // Draw a quad covering the whole framebuffer
557                 m_vertices.push_back(Vec4(-1.0f,  1.0f, 0.0f, 1.0f));
558                 m_vertices.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
559                 m_vertices.push_back(Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
560                 m_vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
561                 VkDeviceSize vertexBufferSize   = sizeInBytes(m_vertices);
562                 m_vertexBuffer                                  = Buffer::createAndAlloc        (vk, device, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), allocator, MemoryRequirement::HostVisible);
563
564
565                 deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), m_vertices.data(), static_cast<std::size_t>(vertexBufferSize));
566                 flushAlloc(vk, device, m_vertexBuffer->getBoundMemory());
567
568                 m_vertexModule                          = createShaderModule    (vk, device, m_context.getBinaryCollection().get("vert"), 0u);
569                 m_fragmentModule                        = createShaderModule    (vk, device, m_context.getBinaryCollection().get("frag"), 0u);
570
571                 if (!m_params.groupParams->useDynamicRendering)
572                 {
573                         m_renderPass                    = makeRenderPass                (vk, device, colorFormat);
574                         m_framebuffer                   = makeFramebuffer               (vk, device, *m_renderPass, m_colorAttachment.get(),
575                                                                                                                          static_cast<deUint32>(m_renderSize.x()),
576                                                                                                                          static_cast<deUint32>(m_renderSize.y()));
577                 }
578
579                 m_pipelineLayout                        = makePipelineLayout    (vk, device);
580
581                 generateDiscardRectangles(m_renderSize, m_params.numRectangles, m_rectangles);
582                 m_pipeline                                      = makeGraphicsPipeline  (vk, device, *m_pipelineLayout, *m_renderPass, *m_vertexModule, *m_fragmentModule, m_renderSize,
583                                                                                                                          m_params.dynamicDiscardRectangles, discardRectangleMode, m_params.numRectangles,
584                                                                                                                          m_rectangles.data(), m_params.scissorMode, rectScissor);
585                 m_cmdPool                                       = createCommandPool             (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
586                 m_cmdBuffer                                     = allocateCommandBuffer (vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
587         }
588
589         const VkClearValue                      clearValue = makeClearValueColor(m_clearColor);
590         const VkRect2D                          renderArea
591         {
592                 makeOffset2D(0, 0),
593                 makeExtent2D(m_renderSize.x(), m_renderSize.y()),
594         };
595
596         // Write command buffers and submit it
597
598 #ifndef CTS_USES_VULKANSC
599         if (m_params.groupParams->useSecondaryCmdBuffer)
600         {
601                 m_secCmdBuffer = allocateCommandBuffer(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
602
603                 // record secondary command buffer
604                 if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
605                 {
606                         beginSecondaryCmdBuffer(*m_secCmdBuffer, colorFormat, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
607                         beginRendering(vk, *m_secCmdBuffer, *m_colorAttachment, renderArea, clearValue,
608                                                    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_CLEAR);
609                 }
610                 else
611                         beginSecondaryCmdBuffer(*m_secCmdBuffer, colorFormat);
612
613                 drawCommands(*m_secCmdBuffer, rectScissor);
614
615                 if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
616                         vk.cmdEndRendering(*m_secCmdBuffer);
617
618                 endCommandBuffer(vk, *m_secCmdBuffer);
619
620                 // record primary command buffer
621                 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
622                 preRenderCommands(*m_cmdBuffer);
623
624                 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
625                         beginRendering(vk, *m_cmdBuffer, *m_colorAttachment, renderArea, clearValue, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
626                                                    VK_ATTACHMENT_LOAD_OP_CLEAR, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
627
628                 vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
629
630                 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
631                         vk.cmdEndRendering(*m_cmdBuffer);
632         }
633         else if (m_params.groupParams->useDynamicRendering)
634         {
635                 beginCommandBuffer(vk, *m_cmdBuffer);
636
637                 preRenderCommands(*m_cmdBuffer);
638                 beginRendering(vk, *m_cmdBuffer, *m_colorAttachment, renderArea, clearValue,
639                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_CLEAR);
640                 drawCommands(*m_cmdBuffer, rectScissor);
641                 vk.cmdEndRendering(*m_cmdBuffer);
642         }
643 #endif // CTS_USES_VULKANSC
644
645         if (!m_params.groupParams->useDynamicRendering)
646         {
647                 const VkRenderPassBeginInfo renderPassBeginInfo
648                 {
649                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType                      sType;
650                         DE_NULL,                                                                                // const void*                          pNext;
651                         *m_renderPass,                                                                  // VkRenderPass                         renderPass;
652                         *m_framebuffer,                                                                 // VkFramebuffer                        framebuffer;
653                         renderArea,                                                                             // VkRect2D                                     renderArea;
654                         1u,                                                                                             // uint32_t                                     clearValueCount;
655                         &clearValue,                                                                    // const VkClearValue*          pClearValues;
656                 };
657
658                 beginCommandBuffer(vk, *m_cmdBuffer);
659
660                 preRenderCommands(*m_cmdBuffer);
661                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
662                 drawCommands(*m_cmdBuffer, rectScissor);
663                 vk.cmdEndRenderPass(*m_cmdBuffer);
664         }
665
666         copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, m_colorBuffer->object(), tcu::IVec2(m_renderSize.x(), m_renderSize.y()), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, colorSubresourceRange.layerCount);
667         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
668
669         submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
670
671         // Verify results
672         {
673                 const Allocation alloc = m_colorBuffer->getBoundMemory();
674                 invalidateAlloc(vk, device, alloc);
675
676                 const tcu::ConstPixelBufferAccess       resultImage             (mapVkFormat(colorFormat), m_renderSize.x(), m_renderSize.y(), 1u, alloc.getHostPtr());
677                 const tcu::TextureLevel                         referenceImage  = generateReferenceImage(mapVkFormat(colorFormat), m_renderSize, m_params.testMode, m_clearColor,
678                                                                                                                                                                          m_params.numRectangles, m_rectangles, m_params.scissorMode != TEST_SCISSOR_MODE_NONE, rectScissor);
679                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImage.getAccess(), resultImage, Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
680                         TCU_FAIL("Rendered image is not correct");
681         }
682         return tcu::TestStatus::pass("OK");
683 }
684
685 void DiscardRectanglesTestInstance::preRenderCommands(vk::VkCommandBuffer cmdBuffer) const
686 {
687         if (!m_params.groupParams->useDynamicRendering)
688                 return;
689
690         const DeviceInterface& vk = m_context.getDeviceInterface();
691         initialTransitionColor2DImage(vk, cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
692                                                                   VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
693 }
694
695 void DiscardRectanglesTestInstance::drawCommands(vk::VkCommandBuffer cmdBuffer, const VkRect2D& rectScissor) const
696 {
697         const DeviceInterface& vk = m_context.getDeviceInterface();
698         vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
699         {
700                 const VkBuffer vertexBuffer = m_vertexBuffer->object();
701                 const VkDeviceSize vertexBufferOffset = 0ull;
702                 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
703         }
704         if (m_params.dynamicDiscardRectangles)
705         {
706                 vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0u, m_params.numRectangles, m_rectangles.data());
707         }
708         if (m_params.scissorMode == TEST_SCISSOR_MODE_DYNAMIC)
709         {
710                 vk.cmdSetScissor(cmdBuffer, 0u, 1u, &rectScissor);
711         }
712         vk.cmdDraw(cmdBuffer, static_cast<deUint32>(m_vertices.size()), 1u, 0u, 0u);    // two triangles
713 }
714
715 #ifndef CTS_USES_VULKANSC
716 void DiscardRectanglesTestInstance::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkFormat colorFormat, VkRenderingFlagsKHR renderingFlags) const
717 {
718         VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
719         {
720                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,                // VkStructureType                                      sType;
721                 DE_NULL,                                                                                                                                // const void*                                          pNext;
722                 renderingFlags,                                                                                                                 // VkRenderingFlagsKHR                          flags;
723                 0u,                                                                                                                                             // uint32_t                                                     viewMask;
724                 1u,                                                                                                                                             // uint32_t                                                     colorAttachmentCount;
725                 &colorFormat,                                                                                                                   // const VkFormat*                                      pColorAttachmentFormats;
726                 VK_FORMAT_UNDEFINED,                                                                                                    // VkFormat                                                     depthAttachmentFormat;
727                 VK_FORMAT_UNDEFINED,                                                                                                    // VkFormat                                                     stencilAttachmentFormat;
728                 VK_SAMPLE_COUNT_1_BIT,                                                                                                  // VkSampleCountFlagBits                        rasterizationSamples;
729         };
730         const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
731
732         VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
733         if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
734                 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
735
736         const VkCommandBufferBeginInfo commandBufBeginParams
737         {
738                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                                                    // VkStructureType                                      sType;
739                 DE_NULL,                                                                                                                                // const void*                                          pNext;
740                 usageFlags,                                                                                                                             // VkCommandBufferUsageFlags            flags;
741                 &bufferInheritanceInfo
742         };
743
744         const DeviceInterface& vk = m_context.getDeviceInterface();
745         VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
746 }
747 #endif // CTS_USES_VULKANSC
748
749 class DiscardRectanglesTestCase : public TestCase
750 {
751 public:
752                                                                 DiscardRectanglesTestCase       (tcu::TestContext &context,
753                                                                                                                          const char *name,
754                                                                                                                          const char *description,
755                                                                                                                          TestParams params);
756         virtual                                         ~DiscardRectanglesTestCase      (void) {}
757
758         virtual TestInstance*           createInstance                          (Context& context)      const;
759         virtual void                            initPrograms                            (SourceCollections& programCollection) const;
760         virtual void                            checkSupport                            (Context& context) const;
761
762 private:
763         const TestParams                        m_params;
764 };
765
766 DiscardRectanglesTestCase::DiscardRectanglesTestCase    (tcu::TestContext &context,
767                                                                                                                  const char *name,
768                                                                                                                  const char *description,
769                                                                                                                  TestParams params)
770         : TestCase              (context, name, description)
771         , m_params              (params)
772 {
773 }
774
775 void DiscardRectanglesTestCase::initPrograms(SourceCollections& programCollection) const
776 {
777         // Vertex
778         {
779                 std::ostringstream src;
780                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
781                         << "\n"
782                         << "layout(location = 0) in highp vec4 position;\n"
783                         << "layout(location = 0) out highp vec4 vsColor;\n"
784                         << "\n"
785                         << "out gl_PerVertex {\n"
786                         << "   vec4 gl_Position;\n"
787                         << "};\n"
788                         << "\n"
789                         << "void main (void)\n"
790                         << "{\n"
791                         << "    gl_Position = position;\n"
792                         << "    vsColor     = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
793                         << "}\n";
794                 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
795         }
796
797         // Fragment
798         {
799                 std::ostringstream src;
800                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
801                         << "\n"
802                         << "layout(location = 0) in highp vec4 vsColor;\n"
803                         << "layout(location = 0) out highp vec4 fsColor;\n"
804                         << "\n"
805                         << "void main (void)\n"
806                         << "{\n"
807                         << "    fsColor     = vsColor;\n"
808                         << "}\n";
809                 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
810         }
811 }
812
813 void DiscardRectanglesTestCase::checkSupport (Context& context) const
814 {
815         context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
816         if (m_params.groupParams->useDynamicRendering)
817                 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
818 }
819
820 TestInstance* DiscardRectanglesTestCase::createInstance (Context& context) const
821 {
822         return new DiscardRectanglesTestInstance(context, m_params);
823 }
824
825 void createTests (tcu::TestCaseGroup* testGroup, const SharedGroupParams groupParams)
826 {
827         tcu::TestContext&       testCtx                                                                                 = testGroup->getTestContext();
828         deUint32                        numRect [NUM_RECT_TESTS]                                                = { 1, 2, 3, 4,  8, 16};
829         std::string                     modeName [TEST_MODE_COUNT]                                              = { "inclusive_", "exclusive_" };
830         std::string                     scissorName [TEST_SCISSOR_MODE_COUNT]                   = { "", "scissor_", "dynamic_scissor_" };
831         std::string                     dynamicName [NUM_DYNAMIC_DISCARD_TYPE_TESTS]    = { "", "dynamic_discard_" };
832
833         for (deUint32 dynamic = 0 ; dynamic < NUM_DYNAMIC_DISCARD_TYPE_TESTS; dynamic++)
834         {
835                 for (deUint32 scissor = 0 ; scissor < TEST_SCISSOR_MODE_COUNT; scissor++)
836                 {
837                         for (deUint32 mode = 0; mode < TEST_MODE_COUNT; mode++)
838                         {
839                                 for (deUint32 rect = 0; rect < NUM_RECT_TESTS; rect++)
840                                 {
841                                         std::ostringstream      name;
842                                         TestParams                      params
843                                         {
844                                                 (TestMode)mode,                                         // TestMode                                     testMode;
845                                                 numRect[rect],                                          // deUint32                                     numRectangles;
846                                                 dynamic ? DE_TRUE : DE_FALSE,           // deBool                                       dynamicDiscardRectangles;
847                                                 (TestScissorMode)scissor,                       // TestScissorMode                      scissorMode;
848                                                 groupParams,                                            // const SharedGroupParams      groupParams;
849                                         };
850
851                                         name << dynamicName[dynamic] << scissorName[scissor] << modeName[mode] << "rect_" << numRect[rect];
852
853                                         testGroup->addChild(new DiscardRectanglesTestCase(testCtx, name.str().c_str(), "", params));
854                                 }
855                         }
856                 }
857         }
858 }
859 }       // Anonymous
860
861 tcu::TestCaseGroup* createDiscardRectanglesTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
862 {
863         return createTestGroup(testCtx, "discard_rectangles", "Discard Rectangles tests", createTests, groupParams);
864 }
865
866 }       // Draw
867 }       //vkt