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(),
55 params.pipelineConstructionType);
56 }
57
initPrograms(SourceCollections & programCollection,const MatchedAttachmentsTestParams params)58 void initPrograms(SourceCollections &programCollection, const MatchedAttachmentsTestParams params)
59 {
60 DE_UNREF(params);
61
62 programCollection.glslSources.add("color_vert") << glu::VertexSource("#version 450\n"
63 "\n"
64 "void main(){\n"
65 " gl_Position = vec4(1);\n"
66 "}\n");
67
68 programCollection.glslSources.add("color_frag")
69 << glu::FragmentSource("#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(
85 ShaderWrapper(vk, vkDevice, context.getBinaryCollection().get("color_vert"), 0));
86 const ShaderWrapper fragmentShaderModule(
87 ShaderWrapper(vk, vkDevice, context.getBinaryCollection().get("color_frag"), 0));
88
89 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
90 0u, // uint32_t binding;
91 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType;
92 1u, // uint32_t descriptorCount;
93 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
94 DE_NULL // const VkSampler* pImmutableSamplers;
95 };
96
97 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
98 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
99 DE_NULL, // const void* pNext;
100 0u, // VkDescriptorSetLayoutCreateFlags flags;
101 1u, // uint32_t bindingCount;
102 &descriptorSetLayoutBinding // const VkDescriptorSetLayoutBinding* pBindings;
103 };
104
105 const Unique<VkDescriptorSetLayout> descriptorSetLayout(
106 createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutCreateInfo, DE_NULL));
107
108 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
109 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
110 DE_NULL, // const void* pNext;
111 0u, // VkPipelineLayoutCreateFlags flags;
112 1u, // uint32_t setLayoutCount;
113 &(*descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
114 0u, // uint32_t pushConstantRangeCount;
115 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
116 };
117
118 const PipelineLayoutWrapper pipelineLayout(params.pipelineConstructionType, vk, vkDevice, &pipelineLayoutCreateInfo,
119 DE_NULL);
120
121 const VkAttachmentDescription descs[2] = {
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 const VkAttachmentReference color = {
146 0u, // uint32_t attachment;
147 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
148 };
149
150 const VkAttachmentReference input = {
151 1u, // uint32_t attachment;
152 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
153 };
154
155 const VkSubpassDescription subpassDescription = {
156 0u, // VkSubpassDescriptionFlags flags;
157 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
158 1u, // uint32_t inputAttachmentCount;
159 &input, // const VkAttachmentReference* pInputAttachments;
160 1u, // uint32_t colorAttachmentCount;
161 &color, // const VkAttachmentReference* pColorAttachments;
162 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
163 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
164 0u, // uint32_t preserveAttachmentCount;
165 DE_NULL // const uint32_t* pPreserveAttachments;
166 };
167
168 const VkRenderPassCreateInfo renderPassCreateInfo = {
169 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
170 DE_NULL, // const void* pNext;
171 0u, // VkRenderPassCreateFlags flags;
172 2u, // uint32_t attachmentCount;
173 descs, // const VkAttachmentDescription* pAttachments;
174 1u, // uint32_t subpassCount;
175 &subpassDescription, // const VkSubpassDescription* pSubpasses;
176 0u, // uint32_t dependencyCount;
177 DE_NULL // const VkSubpassDependency* pDependencies;
178 };
179
180 RenderPassWrapper renderPass(params.pipelineConstructionType, vk, vkDevice, &renderPassCreateInfo);
181
182 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {
183 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
184 DE_NULL, // const void* pNext;
185 #ifndef CTS_USES_VULKANSC
186 (VkPipelineCacheCreateFlags)0u, // VkPipelineCacheCreateFlags flags;
187 0u, // size_t initialDataSize;
188 DE_NULL // const void* pInitialData;
189 #else
190 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
191 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
192 context.getResourceInterface()->getCacheDataSize(), // uintptr_t initialDataSize;
193 context.getResourceInterface()->getCacheData() // const void* pInitialData;
194 #endif // CTS_USES_VULKANSC
195 };
196
197 const Unique<VkPipelineCache> pipelineCache(createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo));
198
199 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
200 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
201 DE_NULL, // const void* pNext;
202 0u, // VkPipelineVertexInputStateCreateFlags flags;
203 0u, // uint32_t vertexBindingDescriptionCount;
204 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
205 0u, // uint32_t vertexAttributeDescriptionCount;
206 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
207 };
208
209 const VkDynamicState dynamicState[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
210
211 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
212 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
213 DE_NULL, // const void* pNext;
214 0u, // VkPipelineDynamicStateCreateFlags flags;
215 2u, // uint32_t dynamicStateCount;
216 dynamicState // const VkDynamicState* pDynamicStates;
217 };
218
219 const std::vector<VkViewport> viewport{};
220 const std::vector<VkRect2D> scissor{};
221 GraphicsPipelineWrapper graphicsPipeline(vki, vk, physicalDevice, vkDevice, context.getDeviceExtensions(),
222 params.pipelineConstructionType);
223 graphicsPipeline.setDynamicState(&dynamicStateCreateInfo)
224 .setDefaultRasterizationState()
225 .setDefaultMultisampleState()
226 .setDefaultColorBlendState()
227 .setupVertexInputState(&vertexInputStateCreateInfo)
228 .setupPreRasterizationShaderState(viewport, scissor, pipelineLayout, *renderPass, 0u, vertexShaderModule)
229 .setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragmentShaderModule)
230 .setupFragmentOutputState(*renderPass, 0u)
231 .setMonolithicPipelineLayout(pipelineLayout)
232 .buildPipeline(params.usePipelineCache ? *pipelineCache : DE_NULL);
233
234 // Passes as long as createGraphicsPipeline didn't crash.
235 return tcu::TestStatus::pass("Pass");
236 }
237
addMatchedAttachmentsTestCasesWithFunctions(tcu::TestCaseGroup * group,PipelineConstructionType pipelineConstructionType)238 void addMatchedAttachmentsTestCasesWithFunctions(tcu::TestCaseGroup *group,
239 PipelineConstructionType pipelineConstructionType)
240 {
241 // Input attachments are not supported with dynamic rendering
242 if (!isConstructionTypeShaderObject(pipelineConstructionType))
243 {
244 const MatchedAttachmentsTestParams useCache = {pipelineConstructionType, true};
245 addFunctionCaseWithPrograms(group, "cache", checkSupport, initPrograms, testMatchedAttachments, useCache);
246
247 const MatchedAttachmentsTestParams noCache = {pipelineConstructionType, false};
248 addFunctionCaseWithPrograms(group, "no_cache", checkSupport, initPrograms, testMatchedAttachments, noCache);
249 }
250 }
251
252 } // namespace
253
createMatchedAttachmentsTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)254 tcu::TestCaseGroup *createMatchedAttachmentsTests(tcu::TestContext &testCtx,
255 PipelineConstructionType pipelineConstructionType)
256 {
257 return createTestGroup(testCtx, "matched_attachments", addMatchedAttachmentsTestCasesWithFunctions,
258 pipelineConstructionType);
259 }
260
261 } // namespace pipeline
262 } // namespace vkt
263