xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/draw/vktDrawPointClampTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2023 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief glPointSize clamp test
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktDrawPointClampTests.hpp"
25 
26 #include "vktTestCaseUtil.hpp"
27 
28 #include "vkPrograms.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vkMemUtil.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkImageUtil.hpp"
36 
37 #include "tcuTestLog.hpp"
38 #include "tcuFormatUtil.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "tcuImageCompare.hpp"
41 
42 #include "deUniquePtr.hpp"
43 #include "deMath.h"
44 
45 namespace vkt
46 {
47 namespace Draw
48 {
49 
50 using namespace vk;
51 using namespace de;
52 
53 struct Vertex
54 {
55     tcu::Vec4 pos;
56     tcu::Vec4 color;
57 };
58 
createPointSizeClampProgs(SourceCollections & dst)59 void createPointSizeClampProgs(SourceCollections &dst)
60 {
61     std::stringstream vertShader;
62     vertShader << "#version 450\n"
63                << "layout(location = 0) in vec4 in_position;\n"
64                << "layout(location = 1) in vec4 in_color;\n"
65                << "layout(push_constant) uniform pointSizeBlk {\n"
66                << "    float psize;\n"
67                << "} in_pointSize;\n"
68                << "layout(location = 0) out vec4 out_color;\n"
69 
70                << "out gl_PerVertex {\n"
71                << "    vec4  gl_Position;\n"
72                << "    float gl_PointSize;\n"
73                << "};\n"
74                << "void main() {\n"
75                << "    gl_PointSize = in_pointSize.psize;\n"
76                << "    gl_Position  = in_position;\n"
77                << "    out_color    = in_color;\n"
78                << "}\n";
79 
80     std::stringstream fragShader;
81     fragShader << "#version 450\n"
82                << "layout(location = 0) flat in vec4 in_color;\n"
83                << "layout(location = 0) out vec4 out_color;\n"
84                << "void main()\n"
85                << "{\n"
86                << "    out_color = in_color;\n"
87                << "}\n";
88 
89     dst.glslSources.add("vert") << glu::VertexSource(vertShader.str());
90     dst.glslSources.add("frag") << glu::FragmentSource(fragShader.str());
91 }
92 
renderPointSizeClampTest(Context & context)93 tcu::TestStatus renderPointSizeClampTest(Context &context)
94 {
95     const VkDevice vkDevice          = context.getDevice();
96     const DeviceInterface &vk        = context.getDeviceInterface();
97     const VkQueue queue              = context.getUniversalQueue();
98     const uint32_t queueFamilyIndex  = context.getUniversalQueueFamilyIndex();
99     const VkPhysicalDevice phyDevice = context.getPhysicalDevice();
100     SimpleAllocator memAlloc(vk, vkDevice,
101                              getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), phyDevice));
102     const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
103     const tcu::Vec4 clearColor(0.0f, 1.0f, 0.0f, 1.0f);
104     const tcu::Vec4 pointColor(0.0f, 0.0f, 0.0f, 0.0f);
105 
106     const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(context.getInstanceInterface(), phyDevice);
107     if (!features.largePoints)
108         throw tcu::NotSupportedError("Large points not supported");
109 
110     VkPhysicalDeviceProperties phyDevProps;
111     context.getInstanceInterface().getPhysicalDeviceProperties(phyDevice, &phyDevProps);
112 
113     //float minPointSizeRange = phyDevProps.limits.pointSizeRange[0];
114     float maxPointSizeRange = phyDevProps.limits.pointSizeRange[1];
115 
116     uint32_t fbWidthSize = deCeilFloatToInt32(maxPointSizeRange * 0.5f) + 1;
117 
118     const tcu::IVec2 renderSize(fbWidthSize, 1);
119 
120     const float testPointSize = deFloatFloor(maxPointSizeRange * 2.0f);
121 
122     VkPushConstantRange pcPointSize;
123     pcPointSize.offset     = 0;
124     pcPointSize.size       = sizeof(float);
125     pcPointSize.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
126 
127     float pxCenter = (float)fbWidthSize - 0.25f;
128 
129     float testPointXCoord = ((2.0f * pxCenter) / (float)fbWidthSize) - 1.0f;
130 
131     const struct Vertex vertices[] = {{tcu::Vec4(testPointXCoord, 0.0f, 0.0f, 1.0f), pointColor}};
132 
133     const VkBufferCreateInfo vertexBufferParams = {
134         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
135         DE_NULL,                              // pNext
136         0u,                                   // flags
137         (VkDeviceSize)sizeof(vertices),       // size
138         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    // usage
139         VK_SHARING_MODE_EXCLUSIVE,            // sharingMode
140         1u,                                   // queueFamilyIndexCount
141         &queueFamilyIndex,                    // pQueueFamilyIndices
142     };
143     const Unique<VkBuffer> vertexBuffer(createBuffer(vk, vkDevice, &vertexBufferParams));
144     const UniquePtr<Allocation> vertexBufferMemory(
145         memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));
146 
147     VK_CHECK(
148         vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
149 
150     const VkDeviceSize imageSizeBytes              = (VkDeviceSize)(sizeof(uint32_t) * renderSize.x() * renderSize.y());
151     const VkBufferCreateInfo readImageBufferParams = {
152         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
153         DE_NULL,                              // pNext
154         (VkBufferCreateFlags)0u,              // flags
155         imageSizeBytes,                       // size
156         VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // usage
157         VK_SHARING_MODE_EXCLUSIVE,            // sharingMode
158         1u,                                   // queueFamilyIndexCount
159         &queueFamilyIndex,                    // pQueueFamilyIndices
160     };
161     const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
162     const UniquePtr<Allocation> readImageBufferMemory(
163         memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
164 
165     VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(),
166                                  readImageBufferMemory->getOffset()));
167 
168     const VkImageCreateInfo imageParams = {
169         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                   // sType
170         DE_NULL,                                                               // pNext
171         0u,                                                                    // flags
172         VK_IMAGE_TYPE_2D,                                                      // imageType
173         colorFormat,                                                           // format
174         {(uint32_t)renderSize.x(), (uint32_t)renderSize.y(), 1},               // extent
175         1u,                                                                    // mipLevels
176         1u,                                                                    // arraySize
177         VK_SAMPLE_COUNT_1_BIT,                                                 // samples
178         VK_IMAGE_TILING_OPTIMAL,                                               // tiling
179         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage
180         VK_SHARING_MODE_EXCLUSIVE,                                             // sharingMode
181         1u,                                                                    // queueFamilyIndexCount
182         &queueFamilyIndex,                                                     // pQueueFamilyIndices
183         VK_IMAGE_LAYOUT_UNDEFINED,                                             // initialLayout
184     };
185 
186     const Unique<VkImage> image(createImage(vk, vkDevice, &imageParams));
187     const UniquePtr<Allocation> imageMemory(
188         memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any));
189 
190     VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));
191 
192     const Unique<VkRenderPass> renderPass(makeRenderPass(vk, vkDevice, colorFormat));
193 
194     const VkImageViewCreateInfo colorAttViewParams = {
195         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                                                         // sType
196         DE_NULL,                                                                                          // pNext
197         0u,                                                                                               // flags
198         *image,                                                                                           // image
199         VK_IMAGE_VIEW_TYPE_2D,                                                                            // viewType
200         colorFormat,                                                                                      // format
201         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, // components
202         {
203             VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
204             0u,                        // baseMipLevel
205             1u,                        // levelCount
206             0u,                        // baseArrayLayer
207             1u,                        // layerCount
208         },                             // subresourceRange
209     };
210     const Unique<VkImageView> colorAttView(createImageView(vk, vkDevice, &colorAttViewParams));
211 
212     // Pipeline layout
213     const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
214         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
215         DE_NULL,                                       // pNext
216         (vk::VkPipelineLayoutCreateFlags)0,
217         0u,           // setLayoutCount
218         DE_NULL,      // pSetLayouts
219         1u,           // pushConstantRangeCount
220         &pcPointSize, // pPushConstantRanges
221     };
222     const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
223 
224     // Shaders
225     const Unique<VkShaderModule> vertShaderModule(
226         createShaderModule(vk, vkDevice, context.getBinaryCollection().get("vert"), 0));
227     const Unique<VkShaderModule> fragShaderModule(
228         createShaderModule(vk, vkDevice, context.getBinaryCollection().get("frag"), 0));
229 
230     // Pipeline
231     const std::vector<VkViewport> viewports(1, makeViewport(renderSize));
232     const std::vector<VkRect2D> scissors(1, makeRect2D(renderSize));
233 
234     const VkVertexInputBindingDescription vertexInputBindingDescription = {
235         0u,                          // uint32_t             binding
236         sizeof(Vertex),              // uint32_t             stride
237         VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate    inputRate
238     };
239 
240     const VkVertexInputAttributeDescription vertexInputAttributeDescriptionPos = {
241         0u,                            // uint32_t    location
242         0u,                            // uint32_t    binding
243         VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat    format
244         offsetof(Vertex, pos)          // uint32_t    offset
245     };
246 
247     const VkVertexInputAttributeDescription vertexInputAttributeDescriptionColor = {
248         1u,                     // uint32_t    location
249         0u,                     // uint32_t    binding
250         colorFormat,            // VkFormat    format
251         offsetof(Vertex, color) // uint32_t    offset
252     };
253 
254     std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions;
255     vertexInputAttributeDescriptions.resize(2);
256     vertexInputAttributeDescriptions[0] = vertexInputAttributeDescriptionPos;
257     vertexInputAttributeDescriptions[1] = vertexInputAttributeDescriptionColor;
258 
259     const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
260         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                             sType
261         DE_NULL,                                                   // const void*                                 pNext
262         (VkPipelineVertexInputStateCreateFlags)0,                  // VkPipelineVertexInputStateCreateFlags       flags
263         1u,                             // uint32_t                                    vertexBindingDescriptionCount
264         &vertexInputBindingDescription, // const VkVertexInputBindingDescription*      pVertexBindingDescriptions
265         (uint32_t)vertexInputAttributeDescriptions
266             .size(), // uint32_t                                    vertexAttributeDescriptionCount
267         &vertexInputAttributeDescriptions[0] // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
268     };
269 
270     const Unique<VkPipeline> pipeline(makeGraphicsPipeline(
271         vk,                               // const DeviceInterface&            vk
272         vkDevice,                         // const VkDevice                    device
273         *pipelineLayout,                  // const VkPipelineLayout            pipelineLayout
274         *vertShaderModule,                // const VkShaderModule              vertexShaderModule
275         DE_NULL,                          // const VkShaderModule              tessellationControlModule
276         DE_NULL,                          // const VkShaderModule              tessellationEvalModule
277         DE_NULL,                          // const VkShaderModule              geometryShaderModule
278         *fragShaderModule,                // const VkShaderModule              fragmentShaderModule
279         *renderPass,                      // const VkRenderPass                renderPass
280         viewports,                        // const std::vector<VkViewport>&    viewports
281         scissors,                         // const std::vector<VkRect2D>&      scissors
282         VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // const VkPrimitiveTopology                    topology
283         0u,                               // const uint32_t                                subpass
284         0u,                               // const uint32_t                                patchControlPoints
285         &vertexInputStateCreateInfo));    // const VkPipelineVertexInputStateCreateInfo*    vertexInputStateCreateInfo
286 
287     // Framebuffer
288     const VkFramebufferCreateInfo framebufferParams = {
289         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
290         DE_NULL,                                   // pNext
291         0u,                                        // flags
292         *renderPass,                               // renderPass
293         1u,                                        // attachmentCount
294         &*colorAttView,                            // pAttachments
295         (uint32_t)renderSize.x(),                  // width
296         (uint32_t)renderSize.y(),                  // height
297         1u,                                        // layers
298     };
299     const Unique<VkFramebuffer> framebuffer(createFramebuffer(vk, vkDevice, &framebufferParams));
300 
301     const VkCommandPoolCreateInfo cmdPoolParams = {
302         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,      // sType
303         DE_NULL,                                         // pNext
304         VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags
305         queueFamilyIndex,                                // queueFamilyIndex
306     };
307     const Unique<VkCommandPool> cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
308 
309     // Command buffer
310     const VkCommandBufferAllocateInfo cmdBufParams = {
311         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
312         DE_NULL,                                        // pNext
313         *cmdPool,                                       // pool
314         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                // level
315         1u,                                             // bufferCount
316     };
317     const Unique<VkCommandBuffer> cmdBuf(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
318 
319     // Record commands
320     beginCommandBuffer(vk, *cmdBuf);
321 
322     {
323         const VkMemoryBarrier vertFlushBarrier = {
324             VK_STRUCTURE_TYPE_MEMORY_BARRIER,    // sType
325             DE_NULL,                             // pNext
326             VK_ACCESS_HOST_WRITE_BIT,            // srcAccessMask
327             VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // dstAccessMask
328         };
329         const VkImageMemoryBarrier colorAttBarrier = {
330             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                       // sType
331             DE_NULL,                                                                      // pNext
332             0u,                                                                           // srcAccessMask
333             (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // dstAccessMask
334             VK_IMAGE_LAYOUT_UNDEFINED,                                                    // oldLayout
335             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                     // newLayout
336             queueFamilyIndex,                                                             // srcQueueFamilyIndex
337             queueFamilyIndex,                                                             // dstQueueFamilyIndex
338             *image,                                                                       // image
339             {
340                 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
341                 0u,                        // baseMipLevel
342                 1u,                        // levelCount
343                 0u,                        // baseArrayLayer
344                 1u,                        // layerCount
345             }                              // subresourceRange
346         };
347         vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
348                               (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
349                               &colorAttBarrier);
350     }
351 
352     beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()),
353                     clearColor);
354 
355     vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
356     {
357         const VkDeviceSize bindingOffset = 0;
358         vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
359     }
360     vk.cmdPushConstants(*cmdBuf, *pipelineLayout, pcPointSize.stageFlags, pcPointSize.offset, pcPointSize.size,
361                         &testPointSize);
362     vk.cmdDraw(*cmdBuf, 1u, 1u, 0u, 0u);
363     endRenderPass(vk, *cmdBuf);
364     copyImageToBuffer(vk, *cmdBuf, *image, *readImageBuffer, renderSize);
365     endCommandBuffer(vk, *cmdBuf);
366 
367     // Upload vertex data
368     deMemcpy(vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
369     flushAlloc(vk, vkDevice, *vertexBufferMemory);
370 
371     // Submit & wait for completion
372     submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());
373 
374     {
375         invalidateAlloc(vk, vkDevice, *readImageBufferMemory);
376         const tcu::TextureFormat tcuFormat = vk::mapVkFormat(colorFormat);
377         const tcu::ConstPixelBufferAccess resultAccess(tcuFormat, renderSize.x(), renderSize.y(), 1,
378                                                        readImageBufferMemory->getHostPtr());
379 
380         tcu::TextureLevel referenceLevel(tcuFormat, renderSize.x(), renderSize.y());
381         auto referenceAccess = referenceLevel.getAccess();
382         tcu::clear(referenceAccess, pointColor);
383         referenceAccess.setPixel(clearColor, 0, 0);
384 
385         auto &log = context.getTestContext().getLog();
386         const tcu::Vec4 threshold(0.0f, 0.0f, 0.0f, 0.0f);
387 
388         if (!tcu::floatThresholdCompare(log, "Result", "", referenceAccess, resultAccess, threshold,
389                                         tcu::COMPARE_LOG_ON_ERROR))
390             return tcu::TestStatus::fail("Unexpected color in result buffer; check log for details");
391     }
392     return tcu::TestStatus::pass("Rendering succeeded");
393 }
394 
createDrawPointClampTests(tcu::TestContext & testCtx)395 tcu::TestCaseGroup *createDrawPointClampTests(tcu::TestContext &testCtx)
396 {
397     de::MovePtr<tcu::TestCaseGroup> pointClampTests(new tcu::TestCaseGroup(testCtx, "point_size_clamp"));
398 
399     addFunctionCaseWithPrograms(pointClampTests.get(), "point_size_clamp_max", createPointSizeClampProgs,
400                                 renderPointSizeClampTest);
401 
402     return pointClampTests.release();
403 }
404 } // namespace Draw
405 } // namespace vkt
406