1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2018 The Khronos Group Inc.
6 * Copyright (c) 2018 Google Inc.
7 * Copyright (c) 2023 LunarG, Inc.
8 * Copyright (c) 2023 Nintendo
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 *//*!
23 * \file
24 * \brief Matched attachments tests
25 *//*--------------------------------------------------------------------*/
26
27 #include "vktPipelineMatchedAttachmentsTests.hpp"
28 #include "vktTestCase.hpp"
29 #include "vktTestCaseUtil.hpp"
30 #include "vktTestGroupUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkRefUtil.hpp"
34 #include "deUniquePtr.hpp"
35
36 namespace vkt
37 {
38 namespace pipeline
39 {
40
41 using namespace vk;
42
43 namespace
44 {
45
46 struct MatchedAttachmentsTestParams
47 {
48 PipelineConstructionType pipelineConstructionType;
49 bool usePipelineCache;
50 };
51
checkSupport(Context & context,const MatchedAttachmentsTestParams params)52 void checkSupport(Context& context, const MatchedAttachmentsTestParams params)
53 {
54 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), params.pipelineConstructionType);
55 }
56
initPrograms(SourceCollections & programCollection,const MatchedAttachmentsTestParams params)57 void initPrograms (SourceCollections& programCollection, const MatchedAttachmentsTestParams params)
58 {
59 DE_UNREF(params);
60
61 programCollection.glslSources.add("color_vert") << glu::VertexSource(
62 "#version 450\n"
63 "\n"
64 "void main(){\n"
65 " gl_Position = vec4(1);\n"
66 "}\n");
67
68 programCollection.glslSources.add("color_frag") << glu::FragmentSource(
69 "#version 450\n"
70 "\n"
71 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
72 "layout(location=0) out vec4 color;\n"
73 "void main() {\n"
74 " color = subpassLoad(x);\n"
75 "}\n");
76 }
77
testMatchedAttachments(Context & context,const MatchedAttachmentsTestParams params)78 tcu::TestStatus testMatchedAttachments (Context& context, const MatchedAttachmentsTestParams params)
79 {
80 const InstanceInterface& vki = context.getInstanceInterface();
81 const DeviceInterface& vk = context.getDeviceInterface();
82 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
83 const VkDevice vkDevice = context.getDevice();
84 const ShaderWrapper vertexShaderModule (ShaderWrapper(vk, vkDevice, context.getBinaryCollection().get("color_vert"), 0));
85 const ShaderWrapper fragmentShaderModule (ShaderWrapper(vk, vkDevice, context.getBinaryCollection().get("color_frag"), 0));
86
87 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding =
88 {
89 0u, // deUint32 binding;
90 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType;
91 1u, // deUint32 descriptorCount;
92 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
93 DE_NULL // const VkSampler* pImmutableSamplers;
94 };
95
96 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo =
97 {
98 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
99 DE_NULL, // const void* pNext;
100 0u, // VkDescriptorSetLayoutCreateFlags flags;
101 1u, // deUint32 bindingCount;
102 &descriptorSetLayoutBinding // const VkDescriptorSetLayoutBinding* pBindings;
103 } ;
104
105 const Unique<VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutCreateInfo, DE_NULL));
106
107 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
108 {
109 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
110 DE_NULL, // const void* pNext;
111 0u, // VkPipelineLayoutCreateFlags flags;
112 1u, // deUint32 setLayoutCount;
113 &(*descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
114 0u, // deUint32 pushConstantRangeCount;
115 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
116 };
117
118 const PipelineLayoutWrapper pipelineLayout (params.pipelineConstructionType, vk, vkDevice, &pipelineLayoutCreateInfo, DE_NULL);
119
120 const VkAttachmentDescription descs[2] =
121 {
122 {
123 0u, // VkAttachmentDescriptionFlags flags;
124 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
125 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
126 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
127 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
128 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp;
129 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
130 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
131 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
132 },
133 {
134 0u, // VkAttachmentDescriptionFlags flags;
135 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
136 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
137 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
138 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
139 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp;
140 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
141 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
142 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
143 }
144 };
145
146 const VkAttachmentReference color =
147 {
148 0u, // deUint32 attachment;
149 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
150 };
151
152 const VkAttachmentReference input =
153 {
154 1u, // deUint32 attachment;
155 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
156 };
157
158 const VkSubpassDescription subpassDescription =
159 {
160 0u, // VkSubpassDescriptionFlags flags;
161 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
162 1u, // deUint32 inputAttachmentCount;
163 &input, // const VkAttachmentReference* pInputAttachments;
164 1u, // deUint32 colorAttachmentCount;
165 &color, // const VkAttachmentReference* pColorAttachments;
166 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
167 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
168 0u, // deUint32 preserveAttachmentCount;
169 DE_NULL // const deUint32* pPreserveAttachments;
170 };
171
172 const VkRenderPassCreateInfo renderPassCreateInfo =
173 {
174 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
175 DE_NULL, // const void* pNext;
176 0u, // VkRenderPassCreateFlags flags;
177 2u, // deUint32 attachmentCount;
178 descs, // const VkAttachmentDescription* pAttachments;
179 1u, // deUint32 subpassCount;
180 &subpassDescription, // const VkSubpassDescription* pSubpasses;
181 0u, // deUint32 dependencyCount;
182 DE_NULL // const VkSubpassDependency* pDependencies;
183 };
184
185 RenderPassWrapper renderPass (params.pipelineConstructionType, vk, vkDevice, &renderPassCreateInfo);
186
187 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
188 {
189 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
190 DE_NULL, // const void* pNext;
191 #ifndef CTS_USES_VULKANSC
192 (VkPipelineCacheCreateFlags)0u, // VkPipelineCacheCreateFlags flags;
193 0u, // size_t initialDataSize;
194 DE_NULL // const void* pInitialData;
195 #else
196 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
197 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
198 context.getResourceInterface()->getCacheDataSize(), // deUintptr initialDataSize;
199 context.getResourceInterface()->getCacheData() // const void* pInitialData;
200 #endif // CTS_USES_VULKANSC
201 };
202
203 const Unique<VkPipelineCache> pipelineCache (createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo));
204
205 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
206 {
207 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
208 DE_NULL, // const void* pNext;
209 0u, // VkPipelineVertexInputStateCreateFlags flags;
210 0u, // deUint32 vertexBindingDescriptionCount;
211 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
212 0u, // deUint32 vertexAttributeDescriptionCount;
213 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
214 };
215
216 const VkDynamicState dynamicState[] =
217 {
218 VK_DYNAMIC_STATE_VIEWPORT,
219 VK_DYNAMIC_STATE_SCISSOR
220 };
221
222 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
223 {
224 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
225 DE_NULL, // const void* pNext;
226 0u, // VkPipelineDynamicStateCreateFlags flags;
227 2u, // deUint32 dynamicStateCount;
228 dynamicState // const VkDynamicState* pDynamicStates;
229 };
230
231 const std::vector<VkViewport> viewport{};
232 const std::vector<VkRect2D> scissor {};
233 GraphicsPipelineWrapper graphicsPipeline(vki, vk, physicalDevice, vkDevice, context.getDeviceExtensions(), params.pipelineConstructionType);
234 graphicsPipeline.setDynamicState(&dynamicStateCreateInfo)
235 .setDefaultRasterizationState()
236 .setDefaultMultisampleState()
237 .setDefaultColorBlendState()
238 .setupVertexInputState(&vertexInputStateCreateInfo)
239 .setupPreRasterizationShaderState(viewport,
240 scissor,
241 pipelineLayout,
242 *renderPass,
243 0u,
244 vertexShaderModule)
245 .setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragmentShaderModule)
246 .setupFragmentOutputState(*renderPass, 0u)
247 .setMonolithicPipelineLayout(pipelineLayout)
248 .buildPipeline(params.usePipelineCache ? *pipelineCache : DE_NULL);
249
250 // Passes as long as createGraphicsPipeline didn't crash.
251 return tcu::TestStatus::pass("Pass");
252 }
253
addMatchedAttachmentsTestCasesWithFunctions(tcu::TestCaseGroup * group,PipelineConstructionType pipelineConstructionType)254 void addMatchedAttachmentsTestCasesWithFunctions (tcu::TestCaseGroup* group, PipelineConstructionType pipelineConstructionType)
255 {
256 // Input attachments are not supported with dynamic rendering
257 if (!isConstructionTypeShaderObject(pipelineConstructionType))
258 {
259 const MatchedAttachmentsTestParams useCache = { pipelineConstructionType, true };
260 addFunctionCaseWithPrograms(group, "cache", checkSupport, initPrograms, testMatchedAttachments, useCache);
261
262 const MatchedAttachmentsTestParams noCache = { pipelineConstructionType, false };
263 addFunctionCaseWithPrograms(group, "no_cache", checkSupport, initPrograms, testMatchedAttachments, noCache);
264 }
265 }
266
267 } // anonymous
268
createMatchedAttachmentsTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)269 tcu::TestCaseGroup* createMatchedAttachmentsTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
270 {
271 return createTestGroup(testCtx, "matched_attachments", addMatchedAttachmentsTestCasesWithFunctions, pipelineConstructionType);
272 }
273
274 } // pipeline
275 } // vkt
276