xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/geometry/vktGeometryBasicClass.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 The Android Open Source Project
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 Geometry Basic Class
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktGeometryBasicClass.hpp"
26 
27 #include "vkDefs.hpp"
28 #include "vktTestCase.hpp"
29 #include "vktTestCaseUtil.hpp"
30 #include "vkBarrierUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkBuilderUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkMemUtil.hpp"
37 #include "vkCmdUtil.hpp"
38 #include "vkObjUtil.hpp"
39 #include "vkBufferWithMemory.hpp"
40 #include "vkImageWithMemory.hpp"
41 
42 #include <string>
43 
44 namespace vkt
45 {
46 namespace geometry
47 {
48 using namespace vk;
49 using de::MovePtr;
50 using std::size_t;
51 using std::string;
52 using std::vector;
53 using tcu::IVec2;
54 using tcu::TestCaseGroup;
55 using tcu::TestContext;
56 using tcu::TestStatus;
57 using tcu::Vec4;
58 
59 static const int TEST_CANVAS_SIZE = 256;
60 
GeometryExpanderRenderTestInstance(Context & context,const VkPrimitiveTopology primitiveType,const char * name)61 GeometryExpanderRenderTestInstance::GeometryExpanderRenderTestInstance(Context &context,
62                                                                        const VkPrimitiveTopology primitiveType,
63                                                                        const char *name)
64     : TestInstance(context)
65     , m_primitiveType(primitiveType)
66     , m_name(name)
67     , m_numDrawVertices(0)
68 {
69 }
70 
iterate(void)71 tcu::TestStatus GeometryExpanderRenderTestInstance::iterate(void)
72 {
73     const DeviceInterface &vk       = m_context.getDeviceInterface();
74     const VkDevice device           = m_context.getDevice();
75     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
76     const VkQueue queue             = m_context.getUniversalQueue();
77     Allocator &memAlloc             = m_context.getDefaultAllocator();
78     const IVec2 resolution          = IVec2(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
79     const VkFormat colorFormat      = VK_FORMAT_R8G8B8A8_UNORM;
80     const ImageWithMemory colorAttachmentImage(
81         vk, device, memAlloc,
82         makeImageCreateInfo(resolution, colorFormat,
83                             VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT),
84         MemoryRequirement::Any);
85     const Unique<VkRenderPass> renderPass(makeRenderPass(vk, device, colorFormat));
86 
87     const Move<VkPipelineLayout> pipelineLayout(createPipelineLayout(vk, device));
88     const VkImageSubresourceRange colorSubRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
89     const Unique<VkImageView> colorAttachmentView(
90         makeImageView(vk, device, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubRange));
91     const Unique<VkFramebuffer> framebuffer(
92         makeFramebuffer(vk, device, *renderPass, *colorAttachmentView, resolution.x(), resolution.y(), 1u));
93     const Unique<VkCommandPool> cmdPool(
94         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
95     const Unique<VkCommandBuffer> cmdBuffer(
96         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
97 
98     const VkDeviceSize vertexDataSizeBytes = sizeInBytes(m_vertexPosData) + sizeInBytes(m_vertexAttrData);
99     const uint32_t vertexPositionsOffset   = 0u;
100     const uint32_t vertexAtrrOffset        = static_cast<uint32_t>(sizeof(Vec4));
101     const string geometryShaderName =
102         (m_context.getBinaryCollection().contains("geometry_pointsize") &&
103          checkPointSize(m_context.getInstanceInterface(), m_context.getPhysicalDevice())) ?
104             "geometry_pointsize" :
105             "geometry";
106 
107     const Unique<VkPipeline> pipeline(
108         GraphicsPipelineBuilder()
109             .setRenderSize(resolution)
110             .setShader(vk, device, VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vertex"), DE_NULL)
111             .setShader(vk, device, VK_SHADER_STAGE_GEOMETRY_BIT,
112                        m_context.getBinaryCollection().get(geometryShaderName), DE_NULL)
113             .setShader(vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("fragment"),
114                        DE_NULL)
115             .addVertexBinding(makeVertexInputBindingDescription(0u, 2u * vertexAtrrOffset, VK_VERTEX_INPUT_RATE_VERTEX))
116             .addVertexAttribute(
117                 makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, vertexPositionsOffset))
118             .addVertexAttribute(
119                 makeVertexInputAttributeDescription(1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, vertexAtrrOffset))
120             .setPrimitiveTopology(m_primitiveType)
121             .build(vk, device, *pipelineLayout, *renderPass));
122 
123     const VkDeviceSize colorBufferSizeBytes =
124         resolution.x() * resolution.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
125     const BufferWithMemory colorBuffer(vk, device, memAlloc,
126                                        makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
127                                        MemoryRequirement::HostVisible);
128     const BufferWithMemory vertexBuffer(vk, device, memAlloc,
129                                         makeBufferCreateInfo(vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
130                                         MemoryRequirement::HostVisible);
131     {
132         const Allocation &alloc = vertexBuffer.getAllocation();
133         struct DataVec4
134         {
135             Vec4 pos;
136             Vec4 color;
137         };
138 
139         DataVec4 *const pData = static_cast<DataVec4 *>(alloc.getHostPtr());
140         for (int ndx = 0; ndx < m_numDrawVertices; ++ndx)
141         {
142             pData[ndx].pos   = m_vertexPosData[ndx];
143             pData[ndx].color = m_vertexAttrData[ndx];
144         }
145         flushAlloc(vk, device, alloc);
146         // No barrier needed, flushed memory is automatically visible
147     }
148 
149     // Draw commands
150     beginCommandBuffer(vk, *cmdBuffer);
151 
152     // Change color attachment image layout
153     {
154         const VkImageMemoryBarrier colorAttachmentLayoutBarrier =
155             makeImageMemoryBarrier((VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
156                                    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, *colorAttachmentImage, colorSubRange);
157 
158         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
159                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u,
160                               &colorAttachmentLayoutBarrier);
161     }
162 
163     // Begin render pass
164     {
165         const VkRect2D renderArea = {
166             makeOffset2D(0, 0),
167             makeExtent2D(resolution.x(), resolution.y()),
168         };
169         const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
170         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor);
171     }
172 
173     vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
174     {
175         const VkBuffer buffers[]     = {vertexBuffer.get()};
176         const VkDeviceSize offsets[] = {vertexPositionsOffset};
177         vk.cmdBindVertexBuffers(*cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(buffers), buffers, offsets);
178     }
179 
180     bindDescriptorSets(vk, device, memAlloc, *cmdBuffer, *pipelineLayout);
181 
182     drawCommand(*cmdBuffer);
183     endRenderPass(vk, *cmdBuffer);
184 
185     // Copy render result to a host-visible buffer
186     copyImageToBuffer(vk, *cmdBuffer, *colorAttachmentImage, *colorBuffer, resolution);
187 
188     endCommandBuffer(vk, *cmdBuffer);
189     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
190 
191     {
192         // Log the result image.
193         const Allocation &colorBufferAlloc = colorBuffer.getAllocation();
194         invalidateAlloc(vk, device, colorBufferAlloc);
195         const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), resolution.x(), resolution.y(), 1,
196                                                            colorBufferAlloc.getHostPtr());
197 
198         if (!compareWithFileImage(m_context, imagePixelAccess, m_name))
199             return TestStatus::fail("Fail");
200     }
201 
202     return TestStatus::pass("Pass");
203 }
204 
createPipelineLayout(const DeviceInterface & vk,const VkDevice device)205 Move<VkPipelineLayout> GeometryExpanderRenderTestInstance::createPipelineLayout(const DeviceInterface &vk,
206                                                                                 const VkDevice device)
207 {
208     return makePipelineLayout(vk, device);
209 }
210 
drawCommand(const VkCommandBuffer & cmdBuffer)211 void GeometryExpanderRenderTestInstance::drawCommand(const VkCommandBuffer &cmdBuffer)
212 {
213     const DeviceInterface &vk = m_context.getDeviceInterface();
214     vk.cmdDraw(cmdBuffer, static_cast<uint32_t>(m_numDrawVertices), 1u, 0u, 0u);
215 }
216 
217 } // namespace geometry
218 } // namespace vkt
219