1*b7893ccfSSadaf Ebrahimi /*
2*b7893ccfSSadaf Ebrahimi * Copyright (c) 2015-2019 The Khronos Group Inc.
3*b7893ccfSSadaf Ebrahimi * Copyright (c) 2015-2019 Valve Corporation
4*b7893ccfSSadaf Ebrahimi * Copyright (c) 2015-2019 LunarG, Inc.
5*b7893ccfSSadaf Ebrahimi * Copyright (c) 2015-2019 Google, Inc.
6*b7893ccfSSadaf Ebrahimi *
7*b7893ccfSSadaf Ebrahimi * Licensed under the Apache License, Version 2.0 (the "License");
8*b7893ccfSSadaf Ebrahimi * you may not use this file except in compliance with the License.
9*b7893ccfSSadaf Ebrahimi * You may obtain a copy of the License at
10*b7893ccfSSadaf Ebrahimi *
11*b7893ccfSSadaf Ebrahimi * http://www.apache.org/licenses/LICENSE-2.0
12*b7893ccfSSadaf Ebrahimi *
13*b7893ccfSSadaf Ebrahimi * Author: Chia-I Wu <[email protected]>
14*b7893ccfSSadaf Ebrahimi * Author: Chris Forbes <[email protected]>
15*b7893ccfSSadaf Ebrahimi * Author: Courtney Goeltzenleuchter <[email protected]>
16*b7893ccfSSadaf Ebrahimi * Author: Mark Lobodzinski <[email protected]>
17*b7893ccfSSadaf Ebrahimi * Author: Mike Stroyan <[email protected]>
18*b7893ccfSSadaf Ebrahimi * Author: Tobin Ehlis <[email protected]>
19*b7893ccfSSadaf Ebrahimi * Author: Tony Barbour <[email protected]>
20*b7893ccfSSadaf Ebrahimi * Author: Cody Northrop <[email protected]>
21*b7893ccfSSadaf Ebrahimi * Author: Dave Houlton <[email protected]>
22*b7893ccfSSadaf Ebrahimi * Author: Jeremy Kniager <[email protected]>
23*b7893ccfSSadaf Ebrahimi * Author: Shannon McPherson <[email protected]>
24*b7893ccfSSadaf Ebrahimi * Author: John Zulauf <[email protected]>
25*b7893ccfSSadaf Ebrahimi */
26*b7893ccfSSadaf Ebrahimi
27*b7893ccfSSadaf Ebrahimi #include "cast_utils.h"
28*b7893ccfSSadaf Ebrahimi #include "layer_validation_tests.h"
29*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PSOPolygonModeInvalid)30*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PSOPolygonModeInvalid) {
31*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Attempt to use invalid polygon fill modes.");
32*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures device_features = {};
33*b7893ccfSSadaf Ebrahimi device_features.fillModeNonSolid = VK_FALSE;
34*b7893ccfSSadaf Ebrahimi // The sacrificial device object
35*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init(&device_features));
36*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
37*b7893ccfSSadaf Ebrahimi
38*b7893ccfSSadaf Ebrahimi VkPipelineRasterizationStateCreateInfo rs_ci = {};
39*b7893ccfSSadaf Ebrahimi rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
40*b7893ccfSSadaf Ebrahimi rs_ci.pNext = nullptr;
41*b7893ccfSSadaf Ebrahimi rs_ci.lineWidth = 1.0f;
42*b7893ccfSSadaf Ebrahimi rs_ci.rasterizerDiscardEnable = VK_TRUE;
43*b7893ccfSSadaf Ebrahimi
44*b7893ccfSSadaf Ebrahimi auto set_polygonMode = [&](CreatePipelineHelper &helper) { helper.rs_state_ci_ = rs_ci; };
45*b7893ccfSSadaf Ebrahimi
46*b7893ccfSSadaf Ebrahimi // Set polygonMode to POINT while the non-solid fill mode feature is disabled.
47*b7893ccfSSadaf Ebrahimi // Introduce failure by setting unsupported polygon mode
48*b7893ccfSSadaf Ebrahimi rs_ci.polygonMode = VK_POLYGON_MODE_POINT;
49*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_polygonMode, VK_DEBUG_REPORT_ERROR_BIT_EXT,
50*b7893ccfSSadaf Ebrahimi "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
51*b7893ccfSSadaf Ebrahimi
52*b7893ccfSSadaf Ebrahimi // Set polygonMode to LINE while the non-solid fill mode feature is disabled.
53*b7893ccfSSadaf Ebrahimi // Introduce failure by setting unsupported polygon mode
54*b7893ccfSSadaf Ebrahimi rs_ci.polygonMode = VK_POLYGON_MODE_LINE;
55*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_polygonMode, VK_DEBUG_REPORT_ERROR_BIT_EXT,
56*b7893ccfSSadaf Ebrahimi "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
57*b7893ccfSSadaf Ebrahimi
58*b7893ccfSSadaf Ebrahimi // Set polygonMode to FILL_RECTANGLE_NV while the extension is not enabled.
59*b7893ccfSSadaf Ebrahimi // Introduce failure by setting unsupported polygon mode
60*b7893ccfSSadaf Ebrahimi rs_ci.polygonMode = VK_POLYGON_MODE_FILL_RECTANGLE_NV;
61*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_polygonMode, VK_DEBUG_REPORT_ERROR_BIT_EXT,
62*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01414");
63*b7893ccfSSadaf Ebrahimi }
64*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PipelineNotBound)65*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PipelineNotBound) {
66*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call.");
67*b7893ccfSSadaf Ebrahimi
68*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindPipeline-pipeline-parameter");
69*b7893ccfSSadaf Ebrahimi
70*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
71*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
72*b7893ccfSSadaf Ebrahimi
73*b7893ccfSSadaf Ebrahimi VkPipeline badPipeline = CastToHandle<VkPipeline, uintptr_t>(0xbaadb1be);
74*b7893ccfSSadaf Ebrahimi
75*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
76*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
77*b7893ccfSSadaf Ebrahimi
78*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
79*b7893ccfSSadaf Ebrahimi }
80*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PipelineWrongBindPointGraphics)81*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PipelineWrongBindPointGraphics) {
82*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Bind a compute pipeline in the graphics bind point");
83*b7893ccfSSadaf Ebrahimi
84*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindPipeline-pipelineBindPoint-00779");
85*b7893ccfSSadaf Ebrahimi
86*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
87*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
88*b7893ccfSSadaf Ebrahimi
89*b7893ccfSSadaf Ebrahimi CreateComputePipelineHelper pipe(*this);
90*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
91*b7893ccfSSadaf Ebrahimi pipe.InitState();
92*b7893ccfSSadaf Ebrahimi pipe.CreateComputePipeline();
93*b7893ccfSSadaf Ebrahimi
94*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
95*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
96*b7893ccfSSadaf Ebrahimi
97*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
98*b7893ccfSSadaf Ebrahimi }
99*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PipelineWrongBindPointCompute)100*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PipelineWrongBindPointCompute) {
101*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Bind a graphics pipeline in the compute bind point");
102*b7893ccfSSadaf Ebrahimi
103*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindPipeline-pipelineBindPoint-00780");
104*b7893ccfSSadaf Ebrahimi
105*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
106*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
107*b7893ccfSSadaf Ebrahimi
108*b7893ccfSSadaf Ebrahimi CreatePipelineHelper pipe(*this);
109*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
110*b7893ccfSSadaf Ebrahimi pipe.InitState();
111*b7893ccfSSadaf Ebrahimi pipe.CreateGraphicsPipeline();
112*b7893ccfSSadaf Ebrahimi
113*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
114*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
115*b7893ccfSSadaf Ebrahimi
116*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
117*b7893ccfSSadaf Ebrahimi }
118*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PipelineWrongBindPointRayTracing)119*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PipelineWrongBindPointRayTracing) {
120*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Bind a graphics pipeline in the ray-tracing bind point");
121*b7893ccfSSadaf Ebrahimi
122*b7893ccfSSadaf Ebrahimi if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
123*b7893ccfSSadaf Ebrahimi m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
124*b7893ccfSSadaf Ebrahimi } else {
125*b7893ccfSSadaf Ebrahimi printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
126*b7893ccfSSadaf Ebrahimi return;
127*b7893ccfSSadaf Ebrahimi }
128*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
129*b7893ccfSSadaf Ebrahimi
130*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_RAY_TRACING_EXTENSION_NAME)) {
131*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_NV_RAY_TRACING_EXTENSION_NAME);
132*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
133*b7893ccfSSadaf Ebrahimi } else {
134*b7893ccfSSadaf Ebrahimi printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_NV_RAY_TRACING_EXTENSION_NAME);
135*b7893ccfSSadaf Ebrahimi return;
136*b7893ccfSSadaf Ebrahimi }
137*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
138*b7893ccfSSadaf Ebrahimi
139*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindPipeline-pipelineBindPoint-02392");
140*b7893ccfSSadaf Ebrahimi
141*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
142*b7893ccfSSadaf Ebrahimi
143*b7893ccfSSadaf Ebrahimi if (!EnableDeviceProfileLayer()) {
144*b7893ccfSSadaf Ebrahimi printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
145*b7893ccfSSadaf Ebrahimi return;
146*b7893ccfSSadaf Ebrahimi }
147*b7893ccfSSadaf Ebrahimi
148*b7893ccfSSadaf Ebrahimi CreatePipelineHelper pipe(*this);
149*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
150*b7893ccfSSadaf Ebrahimi pipe.InitState();
151*b7893ccfSSadaf Ebrahimi pipe.CreateGraphicsPipeline();
152*b7893ccfSSadaf Ebrahimi
153*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
154*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, pipe.pipeline_);
155*b7893ccfSSadaf Ebrahimi
156*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
157*b7893ccfSSadaf Ebrahimi }
158*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineBadVertexAttributeFormat)159*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineBadVertexAttributeFormat) {
160*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that pipeline validation catches invalid vertex attribute formats");
161*b7893ccfSSadaf Ebrahimi
162*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
163*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
164*b7893ccfSSadaf Ebrahimi
165*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription input_binding;
166*b7893ccfSSadaf Ebrahimi memset(&input_binding, 0, sizeof(input_binding));
167*b7893ccfSSadaf Ebrahimi
168*b7893ccfSSadaf Ebrahimi VkVertexInputAttributeDescription input_attribs;
169*b7893ccfSSadaf Ebrahimi memset(&input_attribs, 0, sizeof(input_attribs));
170*b7893ccfSSadaf Ebrahimi
171*b7893ccfSSadaf Ebrahimi // Pick a really bad format for this purpose and make sure it should fail
172*b7893ccfSSadaf Ebrahimi input_attribs.format = VK_FORMAT_BC2_UNORM_BLOCK;
173*b7893ccfSSadaf Ebrahimi VkFormatProperties format_props = m_device->format_properties(input_attribs.format);
174*b7893ccfSSadaf Ebrahimi if ((format_props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) != 0) {
175*b7893ccfSSadaf Ebrahimi printf("%s Format unsuitable for test; skipped.\n", kSkipPrefix);
176*b7893ccfSSadaf Ebrahimi return;
177*b7893ccfSSadaf Ebrahimi }
178*b7893ccfSSadaf Ebrahimi
179*b7893ccfSSadaf Ebrahimi input_attribs.location = 0;
180*b7893ccfSSadaf Ebrahimi
181*b7893ccfSSadaf Ebrahimi auto set_info = [&](CreatePipelineHelper &helper) {
182*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &input_binding;
183*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
184*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = &input_attribs;
185*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = 1;
186*b7893ccfSSadaf Ebrahimi };
187*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
188*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputAttributeDescription-format-00623");
189*b7893ccfSSadaf Ebrahimi }
190*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,DisabledIndependentBlend)191*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, DisabledIndependentBlend) {
192*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
193*b7893ccfSSadaf Ebrahimi "Generate INDEPENDENT_BLEND by disabling independent blend and then specifying different blend states for two "
194*b7893ccfSSadaf Ebrahimi "attachments");
195*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures features = {};
196*b7893ccfSSadaf Ebrahimi features.independentBlend = VK_FALSE;
197*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init(&features));
198*b7893ccfSSadaf Ebrahimi
199*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
200*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
201*b7893ccfSSadaf Ebrahimi "Invalid Pipeline CreateInfo: If independent blend feature not enabled, all elements of pAttachments must be identical");
202*b7893ccfSSadaf Ebrahimi
203*b7893ccfSSadaf Ebrahimi VkDescriptorSetObj descriptorSet(m_device);
204*b7893ccfSSadaf Ebrahimi descriptorSet.AppendDummy();
205*b7893ccfSSadaf Ebrahimi descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
206*b7893ccfSSadaf Ebrahimi
207*b7893ccfSSadaf Ebrahimi VkPipelineObj pipeline(m_device);
208*b7893ccfSSadaf Ebrahimi // Create a renderPass with two color attachments
209*b7893ccfSSadaf Ebrahimi VkAttachmentReference attachments[2] = {};
210*b7893ccfSSadaf Ebrahimi attachments[0].layout = VK_IMAGE_LAYOUT_GENERAL;
211*b7893ccfSSadaf Ebrahimi attachments[1].attachment = 1;
212*b7893ccfSSadaf Ebrahimi attachments[1].layout = VK_IMAGE_LAYOUT_GENERAL;
213*b7893ccfSSadaf Ebrahimi
214*b7893ccfSSadaf Ebrahimi VkSubpassDescription subpass = {};
215*b7893ccfSSadaf Ebrahimi subpass.pColorAttachments = attachments;
216*b7893ccfSSadaf Ebrahimi subpass.colorAttachmentCount = 2;
217*b7893ccfSSadaf Ebrahimi
218*b7893ccfSSadaf Ebrahimi VkRenderPassCreateInfo rpci = {};
219*b7893ccfSSadaf Ebrahimi rpci.subpassCount = 1;
220*b7893ccfSSadaf Ebrahimi rpci.pSubpasses = &subpass;
221*b7893ccfSSadaf Ebrahimi rpci.attachmentCount = 2;
222*b7893ccfSSadaf Ebrahimi
223*b7893ccfSSadaf Ebrahimi VkAttachmentDescription attach_desc[2] = {};
224*b7893ccfSSadaf Ebrahimi attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM;
225*b7893ccfSSadaf Ebrahimi attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT;
226*b7893ccfSSadaf Ebrahimi attach_desc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
227*b7893ccfSSadaf Ebrahimi attach_desc[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
228*b7893ccfSSadaf Ebrahimi attach_desc[1].format = VK_FORMAT_B8G8R8A8_UNORM;
229*b7893ccfSSadaf Ebrahimi attach_desc[1].samples = VK_SAMPLE_COUNT_1_BIT;
230*b7893ccfSSadaf Ebrahimi attach_desc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
231*b7893ccfSSadaf Ebrahimi attach_desc[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
232*b7893ccfSSadaf Ebrahimi
233*b7893ccfSSadaf Ebrahimi rpci.pAttachments = attach_desc;
234*b7893ccfSSadaf Ebrahimi rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
235*b7893ccfSSadaf Ebrahimi
236*b7893ccfSSadaf Ebrahimi VkRenderPass renderpass;
237*b7893ccfSSadaf Ebrahimi vkCreateRenderPass(m_device->device(), &rpci, NULL, &renderpass);
238*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
239*b7893ccfSSadaf Ebrahimi pipeline.AddShader(&vs);
240*b7893ccfSSadaf Ebrahimi
241*b7893ccfSSadaf Ebrahimi VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {};
242*b7893ccfSSadaf Ebrahimi att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
243*b7893ccfSSadaf Ebrahimi att_state1.blendEnable = VK_TRUE;
244*b7893ccfSSadaf Ebrahimi att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
245*b7893ccfSSadaf Ebrahimi att_state2.blendEnable = VK_FALSE;
246*b7893ccfSSadaf Ebrahimi pipeline.AddColorAttachment(0, att_state1);
247*b7893ccfSSadaf Ebrahimi pipeline.AddColorAttachment(1, att_state2);
248*b7893ccfSSadaf Ebrahimi pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass);
249*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
250*b7893ccfSSadaf Ebrahimi vkDestroyRenderPass(m_device->device(), renderpass, NULL);
251*b7893ccfSSadaf Ebrahimi }
252*b7893ccfSSadaf Ebrahimi
253*b7893ccfSSadaf Ebrahimi // Is the Pipeline compatible with the expectations of the Renderpass/subpasses?
TEST_F(VkLayerTest,PipelineRenderpassCompatibility)254*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PipelineRenderpassCompatibility) {
255*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
256*b7893ccfSSadaf Ebrahimi "Create a graphics pipeline that is incompatible with the requirements of its contained Renderpass/subpasses.");
257*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
258*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
259*b7893ccfSSadaf Ebrahimi
260*b7893ccfSSadaf Ebrahimi VkPipelineColorBlendAttachmentState att_state1 = {};
261*b7893ccfSSadaf Ebrahimi att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
262*b7893ccfSSadaf Ebrahimi att_state1.blendEnable = VK_TRUE;
263*b7893ccfSSadaf Ebrahimi
264*b7893ccfSSadaf Ebrahimi auto set_info = [&](CreatePipelineHelper &helper) {
265*b7893ccfSSadaf Ebrahimi helper.cb_attachments_ = att_state1;
266*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pColorBlendState = nullptr;
267*b7893ccfSSadaf Ebrahimi };
268*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
269*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00753");
270*b7893ccfSSadaf Ebrahimi }
271*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PointSizeFailure)272*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PointSizeFailure) {
273*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Create a pipeline using TOPOLOGY_POINT_LIST but do not set PointSize in vertex shader.");
274*b7893ccfSSadaf Ebrahimi
275*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
276*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
277*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitViewport());
278*b7893ccfSSadaf Ebrahimi
279*b7893ccfSSadaf Ebrahimi // Create VS declaring PointSize but not writing to it
280*b7893ccfSSadaf Ebrahimi const char NoPointSizeVertShader[] =
281*b7893ccfSSadaf Ebrahimi "#version 450\n"
282*b7893ccfSSadaf Ebrahimi "vec2 vertices[3];\n"
283*b7893ccfSSadaf Ebrahimi "out gl_PerVertex\n"
284*b7893ccfSSadaf Ebrahimi "{\n"
285*b7893ccfSSadaf Ebrahimi " vec4 gl_Position;\n"
286*b7893ccfSSadaf Ebrahimi " float gl_PointSize;\n"
287*b7893ccfSSadaf Ebrahimi "};\n"
288*b7893ccfSSadaf Ebrahimi "void main() {\n"
289*b7893ccfSSadaf Ebrahimi " vertices[0] = vec2(-1.0, -1.0);\n"
290*b7893ccfSSadaf Ebrahimi " vertices[1] = vec2( 1.0, -1.0);\n"
291*b7893ccfSSadaf Ebrahimi " vertices[2] = vec2( 0.0, 1.0);\n"
292*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
293*b7893ccfSSadaf Ebrahimi "}\n";
294*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, NoPointSizeVertShader, VK_SHADER_STAGE_VERTEX_BIT, this);
295*b7893ccfSSadaf Ebrahimi
296*b7893ccfSSadaf Ebrahimi // Set Input Assembly to TOPOLOGY POINT LIST
297*b7893ccfSSadaf Ebrahimi auto set_info = [&](CreatePipelineHelper &helper) {
298*b7893ccfSSadaf Ebrahimi // Set Input Assembly to TOPOLOGY POINT LIST
299*b7893ccfSSadaf Ebrahimi helper.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
300*b7893ccfSSadaf Ebrahimi
301*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
302*b7893ccfSSadaf Ebrahimi };
303*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "Pipeline topology is set to POINT_LIST");
304*b7893ccfSSadaf Ebrahimi }
305*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidTopology)306*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidTopology) {
307*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("InvalidTopology.");
308*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures deviceFeatures = {};
309*b7893ccfSSadaf Ebrahimi deviceFeatures.geometryShader = VK_FALSE;
310*b7893ccfSSadaf Ebrahimi deviceFeatures.tessellationShader = VK_FALSE;
311*b7893ccfSSadaf Ebrahimi
312*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init(&deviceFeatures));
313*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitViewport());
314*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
315*b7893ccfSSadaf Ebrahimi
316*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertPointSizeShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
317*b7893ccfSSadaf Ebrahimi
318*b7893ccfSSadaf Ebrahimi VkPrimitiveTopology topology;
319*b7893ccfSSadaf Ebrahimi
320*b7893ccfSSadaf Ebrahimi auto set_info = [&](CreatePipelineHelper &helper) {
321*b7893ccfSSadaf Ebrahimi helper.ia_ci_.topology = topology;
322*b7893ccfSSadaf Ebrahimi helper.ia_ci_.primitiveRestartEnable = VK_TRUE;
323*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
324*b7893ccfSSadaf Ebrahimi };
325*b7893ccfSSadaf Ebrahimi
326*b7893ccfSSadaf Ebrahimi topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
327*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
328*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00428");
329*b7893ccfSSadaf Ebrahimi
330*b7893ccfSSadaf Ebrahimi topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
331*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
332*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00428");
333*b7893ccfSSadaf Ebrahimi
334*b7893ccfSSadaf Ebrahimi topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
335*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
336*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00428");
337*b7893ccfSSadaf Ebrahimi
338*b7893ccfSSadaf Ebrahimi topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
339*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
340*b7893ccfSSadaf Ebrahimi std::vector<string>{"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00428",
341*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00429"});
342*b7893ccfSSadaf Ebrahimi
343*b7893ccfSSadaf Ebrahimi topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
344*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
345*b7893ccfSSadaf Ebrahimi std::vector<string>{"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00428",
346*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00429"});
347*b7893ccfSSadaf Ebrahimi
348*b7893ccfSSadaf Ebrahimi topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
349*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
350*b7893ccfSSadaf Ebrahimi std::vector<string>{"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00428",
351*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00430",
352*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-topology-00737"});
353*b7893ccfSSadaf Ebrahimi
354*b7893ccfSSadaf Ebrahimi topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
355*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
356*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00429");
357*b7893ccfSSadaf Ebrahimi
358*b7893ccfSSadaf Ebrahimi topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
359*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
360*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00429");
361*b7893ccfSSadaf Ebrahimi }
362*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PointSizeGeomShaderFailure)363*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PointSizeGeomShaderFailure) {
364*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
365*b7893ccfSSadaf Ebrahimi "Create a pipeline using TOPOLOGY_POINT_LIST, set PointSize vertex shader, but not in the final geometry stage.");
366*b7893ccfSSadaf Ebrahimi
367*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
368*b7893ccfSSadaf Ebrahimi
369*b7893ccfSSadaf Ebrahimi if ((!m_device->phy().features().geometryShader) || (!m_device->phy().features().shaderTessellationAndGeometryPointSize)) {
370*b7893ccfSSadaf Ebrahimi printf("%s Device does not support the required geometry shader features; skipped.\n", kSkipPrefix);
371*b7893ccfSSadaf Ebrahimi return;
372*b7893ccfSSadaf Ebrahimi }
373*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
374*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitViewport());
375*b7893ccfSSadaf Ebrahimi
376*b7893ccfSSadaf Ebrahimi // Create VS declaring PointSize and writing to it
377*b7893ccfSSadaf Ebrahimi static char const *gsSource =
378*b7893ccfSSadaf Ebrahimi "#version 450\n"
379*b7893ccfSSadaf Ebrahimi "layout (points) in;\n"
380*b7893ccfSSadaf Ebrahimi "layout (points) out;\n"
381*b7893ccfSSadaf Ebrahimi "layout (max_vertices = 1) out;\n"
382*b7893ccfSSadaf Ebrahimi "void main() {\n"
383*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(1.0, 0.5, 0.5, 0.0);\n"
384*b7893ccfSSadaf Ebrahimi " EmitVertex();\n"
385*b7893ccfSSadaf Ebrahimi "}\n";
386*b7893ccfSSadaf Ebrahimi
387*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertPointSizeShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
388*b7893ccfSSadaf Ebrahimi VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
389*b7893ccfSSadaf Ebrahimi
390*b7893ccfSSadaf Ebrahimi auto set_info = [&](CreatePipelineHelper &helper) {
391*b7893ccfSSadaf Ebrahimi helper.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
392*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), gs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
393*b7893ccfSSadaf Ebrahimi };
394*b7893ccfSSadaf Ebrahimi
395*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "Pipeline topology is set to POINT_LIST");
396*b7893ccfSSadaf Ebrahimi }
397*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,BuiltinBlockOrderMismatchVsGs)398*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, BuiltinBlockOrderMismatchVsGs) {
399*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Use different order of gl_Position and gl_PointSize in builtin block interface between VS and GS.");
400*b7893ccfSSadaf Ebrahimi
401*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
402*b7893ccfSSadaf Ebrahimi
403*b7893ccfSSadaf Ebrahimi if (!m_device->phy().features().geometryShader) {
404*b7893ccfSSadaf Ebrahimi printf("%s Device does not support geometry shaders; Skipped.\n", kSkipPrefix);
405*b7893ccfSSadaf Ebrahimi return;
406*b7893ccfSSadaf Ebrahimi }
407*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
408*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitViewport());
409*b7893ccfSSadaf Ebrahimi
410*b7893ccfSSadaf Ebrahimi // Compiled using the GLSL code below. GlslangValidator rearranges the members, but here they are kept in the order provided.
411*b7893ccfSSadaf Ebrahimi // #version 450
412*b7893ccfSSadaf Ebrahimi // layout (points) in;
413*b7893ccfSSadaf Ebrahimi // layout (points) out;
414*b7893ccfSSadaf Ebrahimi // layout (max_vertices = 1) out;
415*b7893ccfSSadaf Ebrahimi // in gl_PerVertex {
416*b7893ccfSSadaf Ebrahimi // float gl_PointSize;
417*b7893ccfSSadaf Ebrahimi // vec4 gl_Position;
418*b7893ccfSSadaf Ebrahimi // } gl_in[];
419*b7893ccfSSadaf Ebrahimi // void main() {
420*b7893ccfSSadaf Ebrahimi // gl_Position = gl_in[0].gl_Position;
421*b7893ccfSSadaf Ebrahimi // gl_PointSize = gl_in[0].gl_PointSize;
422*b7893ccfSSadaf Ebrahimi // EmitVertex();
423*b7893ccfSSadaf Ebrahimi // }
424*b7893ccfSSadaf Ebrahimi
425*b7893ccfSSadaf Ebrahimi const std::string gsSource = R"(
426*b7893ccfSSadaf Ebrahimi OpCapability Geometry
427*b7893ccfSSadaf Ebrahimi OpCapability GeometryPointSize
428*b7893ccfSSadaf Ebrahimi %1 = OpExtInstImport "GLSL.std.450"
429*b7893ccfSSadaf Ebrahimi OpMemoryModel Logical GLSL450
430*b7893ccfSSadaf Ebrahimi OpEntryPoint Geometry %main "main" %_ %gl_in
431*b7893ccfSSadaf Ebrahimi OpExecutionMode %main InputPoints
432*b7893ccfSSadaf Ebrahimi OpExecutionMode %main Invocations 1
433*b7893ccfSSadaf Ebrahimi OpExecutionMode %main OutputPoints
434*b7893ccfSSadaf Ebrahimi OpExecutionMode %main OutputVertices 1
435*b7893ccfSSadaf Ebrahimi OpSource GLSL 450
436*b7893ccfSSadaf Ebrahimi OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
437*b7893ccfSSadaf Ebrahimi OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
438*b7893ccfSSadaf Ebrahimi OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
439*b7893ccfSSadaf Ebrahimi OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
440*b7893ccfSSadaf Ebrahimi OpDecorate %gl_PerVertex Block
441*b7893ccfSSadaf Ebrahimi OpMemberDecorate %gl_PerVertex_0 0 BuiltIn PointSize
442*b7893ccfSSadaf Ebrahimi OpMemberDecorate %gl_PerVertex_0 1 BuiltIn Position
443*b7893ccfSSadaf Ebrahimi OpDecorate %gl_PerVertex_0 Block
444*b7893ccfSSadaf Ebrahimi %void = OpTypeVoid
445*b7893ccfSSadaf Ebrahimi %3 = OpTypeFunction %void
446*b7893ccfSSadaf Ebrahimi %float = OpTypeFloat 32
447*b7893ccfSSadaf Ebrahimi %v4float = OpTypeVector %float 4
448*b7893ccfSSadaf Ebrahimi %uint = OpTypeInt 32 0
449*b7893ccfSSadaf Ebrahimi %uint_1 = OpConstant %uint 1
450*b7893ccfSSadaf Ebrahimi %_arr_float_uint_1 = OpTypeArray %float %uint_1
451*b7893ccfSSadaf Ebrahimi %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
452*b7893ccfSSadaf Ebrahimi %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
453*b7893ccfSSadaf Ebrahimi %_ = OpVariable %_ptr_Output_gl_PerVertex Output
454*b7893ccfSSadaf Ebrahimi %int = OpTypeInt 32 1
455*b7893ccfSSadaf Ebrahimi %int_0 = OpConstant %int 0
456*b7893ccfSSadaf Ebrahimi %gl_PerVertex_0 = OpTypeStruct %float %v4float
457*b7893ccfSSadaf Ebrahimi %_arr_gl_PerVertex_0_uint_1 = OpTypeArray %gl_PerVertex_0 %uint_1
458*b7893ccfSSadaf Ebrahimi %_ptr_Input__arr_gl_PerVertex_0_uint_1 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_1
459*b7893ccfSSadaf Ebrahimi %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_1 Input
460*b7893ccfSSadaf Ebrahimi %_ptr_Input_v4float = OpTypePointer Input %v4float
461*b7893ccfSSadaf Ebrahimi %_ptr_Output_v4float = OpTypePointer Output %v4float
462*b7893ccfSSadaf Ebrahimi %int_1 = OpConstant %int 1
463*b7893ccfSSadaf Ebrahimi %_ptr_Input_float = OpTypePointer Input %float
464*b7893ccfSSadaf Ebrahimi %_ptr_Output_float = OpTypePointer Output %float
465*b7893ccfSSadaf Ebrahimi %main = OpFunction %void None %3
466*b7893ccfSSadaf Ebrahimi %5 = OpLabel
467*b7893ccfSSadaf Ebrahimi %21 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_1
468*b7893ccfSSadaf Ebrahimi %22 = OpLoad %v4float %21
469*b7893ccfSSadaf Ebrahimi %24 = OpAccessChain %_ptr_Output_v4float %_ %int_0
470*b7893ccfSSadaf Ebrahimi OpStore %24 %22
471*b7893ccfSSadaf Ebrahimi %27 = OpAccessChain %_ptr_Input_float %gl_in %int_0 %int_0
472*b7893ccfSSadaf Ebrahimi %28 = OpLoad %float %27
473*b7893ccfSSadaf Ebrahimi %30 = OpAccessChain %_ptr_Output_float %_ %int_1
474*b7893ccfSSadaf Ebrahimi OpStore %30 %28
475*b7893ccfSSadaf Ebrahimi OpEmitVertex
476*b7893ccfSSadaf Ebrahimi OpReturn
477*b7893ccfSSadaf Ebrahimi OpFunctionEnd
478*b7893ccfSSadaf Ebrahimi )";
479*b7893ccfSSadaf Ebrahimi
480*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertPointSizeShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
481*b7893ccfSSadaf Ebrahimi VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
482*b7893ccfSSadaf Ebrahimi
483*b7893ccfSSadaf Ebrahimi auto set_info = [&](CreatePipelineHelper &helper) {
484*b7893ccfSSadaf Ebrahimi helper.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
485*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), gs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
486*b7893ccfSSadaf Ebrahimi };
487*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
488*b7893ccfSSadaf Ebrahimi "Builtin variable inside block doesn't match between");
489*b7893ccfSSadaf Ebrahimi }
490*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,BuiltinBlockSizeMismatchVsGs)491*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, BuiltinBlockSizeMismatchVsGs) {
492*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Use different number of elements in builtin block interface between VS and GS.");
493*b7893ccfSSadaf Ebrahimi
494*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
495*b7893ccfSSadaf Ebrahimi
496*b7893ccfSSadaf Ebrahimi if (!m_device->phy().features().geometryShader) {
497*b7893ccfSSadaf Ebrahimi printf("%s Device does not support geometry shaders; Skipped.\n", kSkipPrefix);
498*b7893ccfSSadaf Ebrahimi return;
499*b7893ccfSSadaf Ebrahimi }
500*b7893ccfSSadaf Ebrahimi
501*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
502*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitViewport());
503*b7893ccfSSadaf Ebrahimi
504*b7893ccfSSadaf Ebrahimi static const char *gsSource =
505*b7893ccfSSadaf Ebrahimi "#version 450\n"
506*b7893ccfSSadaf Ebrahimi "layout (points) in;\n"
507*b7893ccfSSadaf Ebrahimi "layout (points) out;\n"
508*b7893ccfSSadaf Ebrahimi "layout (max_vertices = 1) out;\n"
509*b7893ccfSSadaf Ebrahimi "in gl_PerVertex\n"
510*b7893ccfSSadaf Ebrahimi "{\n"
511*b7893ccfSSadaf Ebrahimi " vec4 gl_Position;\n"
512*b7893ccfSSadaf Ebrahimi " float gl_PointSize;\n"
513*b7893ccfSSadaf Ebrahimi " float gl_ClipDistance[];\n"
514*b7893ccfSSadaf Ebrahimi "} gl_in[];\n"
515*b7893ccfSSadaf Ebrahimi "void main()\n"
516*b7893ccfSSadaf Ebrahimi "{\n"
517*b7893ccfSSadaf Ebrahimi " gl_Position = gl_in[0].gl_Position;\n"
518*b7893ccfSSadaf Ebrahimi " gl_PointSize = gl_in[0].gl_PointSize;\n"
519*b7893ccfSSadaf Ebrahimi " EmitVertex();\n"
520*b7893ccfSSadaf Ebrahimi "}\n";
521*b7893ccfSSadaf Ebrahimi
522*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertPointSizeShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
523*b7893ccfSSadaf Ebrahimi VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
524*b7893ccfSSadaf Ebrahimi
525*b7893ccfSSadaf Ebrahimi auto set_info = [&](CreatePipelineHelper &helper) {
526*b7893ccfSSadaf Ebrahimi helper.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
527*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), gs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
528*b7893ccfSSadaf Ebrahimi };
529*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
530*b7893ccfSSadaf Ebrahimi "Number of elements inside builtin block differ between stages");
531*b7893ccfSSadaf Ebrahimi }
532*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineLayoutExceedsSetLimit)533*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineLayoutExceedsSetLimit) {
534*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Attempt to create a pipeline layout using more than the physical limit of SetLayouts.");
535*b7893ccfSSadaf Ebrahimi
536*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
537*b7893ccfSSadaf Ebrahimi
538*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutBinding layout_binding = {};
539*b7893ccfSSadaf Ebrahimi layout_binding.binding = 0;
540*b7893ccfSSadaf Ebrahimi layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
541*b7893ccfSSadaf Ebrahimi layout_binding.descriptorCount = 1;
542*b7893ccfSSadaf Ebrahimi layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
543*b7893ccfSSadaf Ebrahimi layout_binding.pImmutableSamplers = NULL;
544*b7893ccfSSadaf Ebrahimi
545*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
546*b7893ccfSSadaf Ebrahimi ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
547*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = 1;
548*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = &layout_binding;
549*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayout ds_layout = {};
550*b7893ccfSSadaf Ebrahimi VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
551*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
552*b7893ccfSSadaf Ebrahimi
553*b7893ccfSSadaf Ebrahimi // Create an array of DSLs, one larger than the physical limit
554*b7893ccfSSadaf Ebrahimi const auto excess_layouts = 1 + m_device->phy().properties().limits.maxBoundDescriptorSets;
555*b7893ccfSSadaf Ebrahimi std::vector<VkDescriptorSetLayout> dsl_array(excess_layouts, ds_layout);
556*b7893ccfSSadaf Ebrahimi
557*b7893ccfSSadaf Ebrahimi VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
558*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
559*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pNext = NULL;
560*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.setLayoutCount = excess_layouts;
561*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pSetLayouts = dsl_array.data();
562*b7893ccfSSadaf Ebrahimi
563*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-setLayoutCount-00286");
564*b7893ccfSSadaf Ebrahimi VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
565*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
566*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
567*b7893ccfSSadaf Ebrahimi
568*b7893ccfSSadaf Ebrahimi // Clean up
569*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
570*b7893ccfSSadaf Ebrahimi }
571*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineLayoutExcessPerStageDescriptors)572*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineLayoutExcessPerStageDescriptors) {
573*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Attempt to create a pipeline layout where total descriptors exceed per-stage limits");
574*b7893ccfSSadaf Ebrahimi
575*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
576*b7893ccfSSadaf Ebrahimi
577*b7893ccfSSadaf Ebrahimi uint32_t max_uniform_buffers = m_device->phy().properties().limits.maxPerStageDescriptorUniformBuffers;
578*b7893ccfSSadaf Ebrahimi uint32_t max_storage_buffers = m_device->phy().properties().limits.maxPerStageDescriptorStorageBuffers;
579*b7893ccfSSadaf Ebrahimi uint32_t max_sampled_images = m_device->phy().properties().limits.maxPerStageDescriptorSampledImages;
580*b7893ccfSSadaf Ebrahimi uint32_t max_storage_images = m_device->phy().properties().limits.maxPerStageDescriptorStorageImages;
581*b7893ccfSSadaf Ebrahimi uint32_t max_samplers = m_device->phy().properties().limits.maxPerStageDescriptorSamplers;
582*b7893ccfSSadaf Ebrahimi uint32_t max_combined = std::min(max_samplers, max_sampled_images);
583*b7893ccfSSadaf Ebrahimi uint32_t max_input_attachments = m_device->phy().properties().limits.maxPerStageDescriptorInputAttachments;
584*b7893ccfSSadaf Ebrahimi
585*b7893ccfSSadaf Ebrahimi uint32_t sum_dyn_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffersDynamic;
586*b7893ccfSSadaf Ebrahimi uint32_t sum_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffers;
587*b7893ccfSSadaf Ebrahimi uint32_t sum_dyn_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffersDynamic;
588*b7893ccfSSadaf Ebrahimi uint32_t sum_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffers;
589*b7893ccfSSadaf Ebrahimi uint32_t sum_sampled_images = m_device->phy().properties().limits.maxDescriptorSetSampledImages;
590*b7893ccfSSadaf Ebrahimi uint32_t sum_storage_images = m_device->phy().properties().limits.maxDescriptorSetStorageImages;
591*b7893ccfSSadaf Ebrahimi uint32_t sum_samplers = m_device->phy().properties().limits.maxDescriptorSetSamplers;
592*b7893ccfSSadaf Ebrahimi uint32_t sum_input_attachments = m_device->phy().properties().limits.maxDescriptorSetInputAttachments;
593*b7893ccfSSadaf Ebrahimi
594*b7893ccfSSadaf Ebrahimi // Devices that report UINT32_MAX for any of these limits can't run this test
595*b7893ccfSSadaf Ebrahimi if (UINT32_MAX == std::max({max_uniform_buffers, max_storage_buffers, max_sampled_images, max_storage_images, max_samplers})) {
596*b7893ccfSSadaf Ebrahimi printf("%s Physical device limits report as 2^32-1. Skipping test.\n", kSkipPrefix);
597*b7893ccfSSadaf Ebrahimi return;
598*b7893ccfSSadaf Ebrahimi }
599*b7893ccfSSadaf Ebrahimi
600*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutBinding dslb = {};
601*b7893ccfSSadaf Ebrahimi std::vector<VkDescriptorSetLayoutBinding> dslb_vec = {};
602*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
603*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
604*b7893ccfSSadaf Ebrahimi ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
605*b7893ccfSSadaf Ebrahimi ds_layout_ci.pNext = NULL;
606*b7893ccfSSadaf Ebrahimi VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
607*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
608*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pNext = NULL;
609*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.setLayoutCount = 1;
610*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pSetLayouts = &ds_layout;
611*b7893ccfSSadaf Ebrahimi VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
612*b7893ccfSSadaf Ebrahimi
613*b7893ccfSSadaf Ebrahimi // VU 0fe0023e - too many sampler type descriptors in fragment stage
614*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
615*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
616*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
617*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = max_samplers;
618*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
619*b7893ccfSSadaf Ebrahimi dslb.pImmutableSamplers = NULL;
620*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
621*b7893ccfSSadaf Ebrahimi dslb.binding = 1;
622*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
623*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = max_combined;
624*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
625*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
626*b7893ccfSSadaf Ebrahimi
627*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
628*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
629*b7893ccfSSadaf Ebrahimi VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
630*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
631*b7893ccfSSadaf Ebrahimi
632*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00287");
633*b7893ccfSSadaf Ebrahimi if ((max_samplers + max_combined) > sum_samplers) {
634*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
635*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01677"); // expect all-stages sum too
636*b7893ccfSSadaf Ebrahimi }
637*b7893ccfSSadaf Ebrahimi if (max_combined > sum_sampled_images) {
638*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
639*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01682"); // expect all-stages sum too
640*b7893ccfSSadaf Ebrahimi }
641*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
642*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
643*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
644*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
645*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
646*b7893ccfSSadaf Ebrahimi
647*b7893ccfSSadaf Ebrahimi // VU 0fe00240 - too many uniform buffer type descriptors in vertex stage
648*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
649*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
650*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
651*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = max_uniform_buffers + 1;
652*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
653*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
654*b7893ccfSSadaf Ebrahimi dslb.binding = 1;
655*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
656*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
657*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
658*b7893ccfSSadaf Ebrahimi
659*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
660*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
661*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
662*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
663*b7893ccfSSadaf Ebrahimi
664*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00288");
665*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > sum_uniform_buffers) {
666*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
667*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01678"); // expect all-stages sum too
668*b7893ccfSSadaf Ebrahimi }
669*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > sum_dyn_uniform_buffers) {
670*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
671*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01679"); // expect all-stages sum too
672*b7893ccfSSadaf Ebrahimi }
673*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
674*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
675*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
676*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
677*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
678*b7893ccfSSadaf Ebrahimi
679*b7893ccfSSadaf Ebrahimi // VU 0fe00242 - too many storage buffer type descriptors in compute stage
680*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
681*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
682*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
683*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = max_storage_buffers + 1;
684*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_ALL;
685*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
686*b7893ccfSSadaf Ebrahimi dslb.binding = 1;
687*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
688*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
689*b7893ccfSSadaf Ebrahimi dslb.binding = 2;
690*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
691*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
692*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
693*b7893ccfSSadaf Ebrahimi
694*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
695*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
696*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
697*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
698*b7893ccfSSadaf Ebrahimi
699*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00289");
700*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > sum_dyn_storage_buffers) {
701*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
702*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01681"); // expect all-stages sum too
703*b7893ccfSSadaf Ebrahimi }
704*b7893ccfSSadaf Ebrahimi if (dslb_vec[0].descriptorCount + dslb_vec[2].descriptorCount > sum_storage_buffers) {
705*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
706*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01680"); // expect all-stages sum too
707*b7893ccfSSadaf Ebrahimi }
708*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
709*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
710*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
711*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
712*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
713*b7893ccfSSadaf Ebrahimi
714*b7893ccfSSadaf Ebrahimi // VU 0fe00244 - too many sampled image type descriptors in multiple stages
715*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
716*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
717*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
718*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = max_sampled_images;
719*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
720*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
721*b7893ccfSSadaf Ebrahimi dslb.binding = 1;
722*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
723*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
724*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
725*b7893ccfSSadaf Ebrahimi dslb.binding = 2;
726*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = max_combined;
727*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
728*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
729*b7893ccfSSadaf Ebrahimi
730*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
731*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
732*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
733*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
734*b7893ccfSSadaf Ebrahimi
735*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00290");
736*b7893ccfSSadaf Ebrahimi if (max_combined + 2 * max_sampled_images > sum_sampled_images) {
737*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
738*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01682"); // expect all-stages sum too
739*b7893ccfSSadaf Ebrahimi }
740*b7893ccfSSadaf Ebrahimi if (max_combined > sum_samplers) {
741*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
742*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01677"); // expect all-stages sum too
743*b7893ccfSSadaf Ebrahimi }
744*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
745*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
746*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
747*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
748*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
749*b7893ccfSSadaf Ebrahimi
750*b7893ccfSSadaf Ebrahimi // VU 0fe00246 - too many storage image type descriptors in fragment stage
751*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
752*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
753*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
754*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = 1 + (max_storage_images / 2);
755*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
756*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
757*b7893ccfSSadaf Ebrahimi dslb.binding = 1;
758*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
759*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
760*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
761*b7893ccfSSadaf Ebrahimi
762*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
763*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
764*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
765*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
766*b7893ccfSSadaf Ebrahimi
767*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00291");
768*b7893ccfSSadaf Ebrahimi if (2 * dslb.descriptorCount > sum_storage_images) {
769*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
770*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01683"); // expect all-stages sum too
771*b7893ccfSSadaf Ebrahimi }
772*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
773*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
774*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
775*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
776*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
777*b7893ccfSSadaf Ebrahimi
778*b7893ccfSSadaf Ebrahimi // VU 0fe00d18 - too many input attachments in fragment stage
779*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
780*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
781*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
782*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = 1 + max_input_attachments;
783*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
784*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
785*b7893ccfSSadaf Ebrahimi
786*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
787*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
788*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
789*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
790*b7893ccfSSadaf Ebrahimi
791*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01676");
792*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > sum_input_attachments) {
793*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
794*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01684"); // expect all-stages sum too
795*b7893ccfSSadaf Ebrahimi }
796*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
797*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
798*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
799*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
800*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
801*b7893ccfSSadaf Ebrahimi }
802*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineLayoutExcessDescriptorsOverall)803*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineLayoutExcessDescriptorsOverall) {
804*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Attempt to create a pipeline layout where total descriptors exceed limits");
805*b7893ccfSSadaf Ebrahimi
806*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
807*b7893ccfSSadaf Ebrahimi
808*b7893ccfSSadaf Ebrahimi uint32_t max_uniform_buffers = m_device->phy().properties().limits.maxPerStageDescriptorUniformBuffers;
809*b7893ccfSSadaf Ebrahimi uint32_t max_storage_buffers = m_device->phy().properties().limits.maxPerStageDescriptorStorageBuffers;
810*b7893ccfSSadaf Ebrahimi uint32_t max_sampled_images = m_device->phy().properties().limits.maxPerStageDescriptorSampledImages;
811*b7893ccfSSadaf Ebrahimi uint32_t max_storage_images = m_device->phy().properties().limits.maxPerStageDescriptorStorageImages;
812*b7893ccfSSadaf Ebrahimi uint32_t max_samplers = m_device->phy().properties().limits.maxPerStageDescriptorSamplers;
813*b7893ccfSSadaf Ebrahimi uint32_t max_input_attachments = m_device->phy().properties().limits.maxPerStageDescriptorInputAttachments;
814*b7893ccfSSadaf Ebrahimi
815*b7893ccfSSadaf Ebrahimi uint32_t sum_dyn_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffersDynamic;
816*b7893ccfSSadaf Ebrahimi uint32_t sum_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffers;
817*b7893ccfSSadaf Ebrahimi uint32_t sum_dyn_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffersDynamic;
818*b7893ccfSSadaf Ebrahimi uint32_t sum_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffers;
819*b7893ccfSSadaf Ebrahimi uint32_t sum_sampled_images = m_device->phy().properties().limits.maxDescriptorSetSampledImages;
820*b7893ccfSSadaf Ebrahimi uint32_t sum_storage_images = m_device->phy().properties().limits.maxDescriptorSetStorageImages;
821*b7893ccfSSadaf Ebrahimi uint32_t sum_samplers = m_device->phy().properties().limits.maxDescriptorSetSamplers;
822*b7893ccfSSadaf Ebrahimi uint32_t sum_input_attachments = m_device->phy().properties().limits.maxDescriptorSetInputAttachments;
823*b7893ccfSSadaf Ebrahimi
824*b7893ccfSSadaf Ebrahimi // Devices that report UINT32_MAX for any of these limits can't run this test
825*b7893ccfSSadaf Ebrahimi if (UINT32_MAX == std::max({sum_dyn_uniform_buffers, sum_uniform_buffers, sum_dyn_storage_buffers, sum_storage_buffers,
826*b7893ccfSSadaf Ebrahimi sum_sampled_images, sum_storage_images, sum_samplers, sum_input_attachments})) {
827*b7893ccfSSadaf Ebrahimi printf("%s Physical device limits report as 2^32-1. Skipping test.\n", kSkipPrefix);
828*b7893ccfSSadaf Ebrahimi return;
829*b7893ccfSSadaf Ebrahimi }
830*b7893ccfSSadaf Ebrahimi
831*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutBinding dslb = {};
832*b7893ccfSSadaf Ebrahimi std::vector<VkDescriptorSetLayoutBinding> dslb_vec = {};
833*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
834*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
835*b7893ccfSSadaf Ebrahimi ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
836*b7893ccfSSadaf Ebrahimi ds_layout_ci.pNext = NULL;
837*b7893ccfSSadaf Ebrahimi VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
838*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
839*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pNext = NULL;
840*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.setLayoutCount = 1;
841*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pSetLayouts = &ds_layout;
842*b7893ccfSSadaf Ebrahimi VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
843*b7893ccfSSadaf Ebrahimi
844*b7893ccfSSadaf Ebrahimi // VU 0fe00d1a - too many sampler type descriptors overall
845*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
846*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
847*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
848*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = sum_samplers / 2;
849*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
850*b7893ccfSSadaf Ebrahimi dslb.pImmutableSamplers = NULL;
851*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
852*b7893ccfSSadaf Ebrahimi dslb.binding = 1;
853*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
854*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = sum_samplers - dslb.descriptorCount + 1;
855*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
856*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
857*b7893ccfSSadaf Ebrahimi
858*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
859*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
860*b7893ccfSSadaf Ebrahimi VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
861*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
862*b7893ccfSSadaf Ebrahimi
863*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01677");
864*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > max_samplers) {
865*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
866*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
867*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00287"); // Expect max-per-stage samplers exceeds limits
868*b7893ccfSSadaf Ebrahimi }
869*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > sum_sampled_images) {
870*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
871*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
872*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01682"); // Expect max overall sampled image count exceeds limits
873*b7893ccfSSadaf Ebrahimi }
874*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > max_sampled_images) {
875*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
876*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
877*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00290"); // Expect max per-stage sampled image count exceeds limits
878*b7893ccfSSadaf Ebrahimi }
879*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
880*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
881*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
882*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
883*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
884*b7893ccfSSadaf Ebrahimi
885*b7893ccfSSadaf Ebrahimi // VU 0fe00d1c - too many uniform buffer type descriptors overall
886*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
887*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
888*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
889*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = sum_uniform_buffers + 1;
890*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
891*b7893ccfSSadaf Ebrahimi dslb.pImmutableSamplers = NULL;
892*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
893*b7893ccfSSadaf Ebrahimi
894*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
895*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
896*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
897*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
898*b7893ccfSSadaf Ebrahimi
899*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01678");
900*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > max_uniform_buffers) {
901*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
902*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00288"); // expect max-per-stage too
903*b7893ccfSSadaf Ebrahimi }
904*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
905*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
906*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
907*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
908*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
909*b7893ccfSSadaf Ebrahimi
910*b7893ccfSSadaf Ebrahimi // VU 0fe00d1e - too many dynamic uniform buffer type descriptors overall
911*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
912*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
913*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
914*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = sum_dyn_uniform_buffers + 1;
915*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
916*b7893ccfSSadaf Ebrahimi dslb.pImmutableSamplers = NULL;
917*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
918*b7893ccfSSadaf Ebrahimi
919*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
920*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
921*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
922*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
923*b7893ccfSSadaf Ebrahimi
924*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01679");
925*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > max_uniform_buffers) {
926*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
927*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00288"); // expect max-per-stage too
928*b7893ccfSSadaf Ebrahimi }
929*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
930*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
931*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
932*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
933*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
934*b7893ccfSSadaf Ebrahimi
935*b7893ccfSSadaf Ebrahimi // VU 0fe00d20 - too many storage buffer type descriptors overall
936*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
937*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
938*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
939*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = sum_storage_buffers + 1;
940*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
941*b7893ccfSSadaf Ebrahimi dslb.pImmutableSamplers = NULL;
942*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
943*b7893ccfSSadaf Ebrahimi
944*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
945*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
946*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
947*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
948*b7893ccfSSadaf Ebrahimi
949*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01680");
950*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > max_storage_buffers) {
951*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
952*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00289"); // expect max-per-stage too
953*b7893ccfSSadaf Ebrahimi }
954*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
955*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
956*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
957*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
958*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
959*b7893ccfSSadaf Ebrahimi
960*b7893ccfSSadaf Ebrahimi // VU 0fe00d22 - too many dynamic storage buffer type descriptors overall
961*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
962*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
963*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
964*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = sum_dyn_storage_buffers + 1;
965*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
966*b7893ccfSSadaf Ebrahimi dslb.pImmutableSamplers = NULL;
967*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
968*b7893ccfSSadaf Ebrahimi
969*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
970*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
971*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
972*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
973*b7893ccfSSadaf Ebrahimi
974*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01681");
975*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > max_storage_buffers) {
976*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
977*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00289"); // expect max-per-stage too
978*b7893ccfSSadaf Ebrahimi }
979*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
980*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
981*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
982*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
983*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
984*b7893ccfSSadaf Ebrahimi
985*b7893ccfSSadaf Ebrahimi // VU 0fe00d24 - too many sampled image type descriptors overall
986*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
987*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
988*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
989*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = max_samplers;
990*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
991*b7893ccfSSadaf Ebrahimi dslb.pImmutableSamplers = NULL;
992*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
993*b7893ccfSSadaf Ebrahimi dslb.binding = 1;
994*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
995*b7893ccfSSadaf Ebrahimi // revisit: not robust to odd limits.
996*b7893ccfSSadaf Ebrahimi uint32_t remaining = (max_samplers > sum_sampled_images ? 0 : (sum_sampled_images - max_samplers) / 2);
997*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = 1 + remaining;
998*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
999*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
1000*b7893ccfSSadaf Ebrahimi dslb.binding = 2;
1001*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
1002*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
1003*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
1004*b7893ccfSSadaf Ebrahimi
1005*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
1006*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
1007*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
1008*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
1009*b7893ccfSSadaf Ebrahimi
1010*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01682");
1011*b7893ccfSSadaf Ebrahimi if (std::max(dslb_vec[0].descriptorCount, dslb_vec[1].descriptorCount) > max_sampled_images) {
1012*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
1013*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
1014*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00290"); // Expect max-per-stage sampled images to exceed limits
1015*b7893ccfSSadaf Ebrahimi }
1016*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
1017*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1018*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
1019*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
1020*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1021*b7893ccfSSadaf Ebrahimi
1022*b7893ccfSSadaf Ebrahimi // VU 0fe00d26 - too many storage image type descriptors overall
1023*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
1024*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
1025*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1026*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = sum_storage_images / 2;
1027*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
1028*b7893ccfSSadaf Ebrahimi dslb.pImmutableSamplers = NULL;
1029*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
1030*b7893ccfSSadaf Ebrahimi dslb.binding = 1;
1031*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
1032*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = sum_storage_images - dslb.descriptorCount + 1;
1033*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
1034*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
1035*b7893ccfSSadaf Ebrahimi
1036*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
1037*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
1038*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
1039*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
1040*b7893ccfSSadaf Ebrahimi
1041*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01683");
1042*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > max_storage_images) {
1043*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1044*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00291"); // expect max-per-stage too
1045*b7893ccfSSadaf Ebrahimi }
1046*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
1047*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1048*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
1049*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
1050*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1051*b7893ccfSSadaf Ebrahimi
1052*b7893ccfSSadaf Ebrahimi // VU 0fe00d28 - too many input attachment type descriptors overall
1053*b7893ccfSSadaf Ebrahimi dslb_vec.clear();
1054*b7893ccfSSadaf Ebrahimi dslb.binding = 0;
1055*b7893ccfSSadaf Ebrahimi dslb.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
1056*b7893ccfSSadaf Ebrahimi dslb.descriptorCount = sum_input_attachments + 1;
1057*b7893ccfSSadaf Ebrahimi dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
1058*b7893ccfSSadaf Ebrahimi dslb.pImmutableSamplers = NULL;
1059*b7893ccfSSadaf Ebrahimi dslb_vec.push_back(dslb);
1060*b7893ccfSSadaf Ebrahimi
1061*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = dslb_vec.size();
1062*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = dslb_vec.data();
1063*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
1064*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
1065*b7893ccfSSadaf Ebrahimi
1066*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01684");
1067*b7893ccfSSadaf Ebrahimi if (dslb.descriptorCount > max_input_attachments) {
1068*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1069*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01676"); // expect max-per-stage too
1070*b7893ccfSSadaf Ebrahimi }
1071*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
1072*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1073*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed
1074*b7893ccfSSadaf Ebrahimi pipeline_layout = VK_NULL_HANDLE;
1075*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1076*b7893ccfSSadaf Ebrahimi }
1077*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidCmdBufferPipelineDestroyed)1078*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) {
1079*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a pipeline dependency being destroyed.");
1080*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
1081*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1082*b7893ccfSSadaf Ebrahimi
1083*b7893ccfSSadaf Ebrahimi {
1084*b7893ccfSSadaf Ebrahimi // Use helper to create graphics pipeline
1085*b7893ccfSSadaf Ebrahimi CreatePipelineHelper helper(*this);
1086*b7893ccfSSadaf Ebrahimi helper.InitInfo();
1087*b7893ccfSSadaf Ebrahimi helper.InitState();
1088*b7893ccfSSadaf Ebrahimi helper.CreateGraphicsPipeline();
1089*b7893ccfSSadaf Ebrahimi
1090*b7893ccfSSadaf Ebrahimi // Bind helper pipeline to command buffer
1091*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
1092*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_);
1093*b7893ccfSSadaf Ebrahimi m_commandBuffer->end();
1094*b7893ccfSSadaf Ebrahimi
1095*b7893ccfSSadaf Ebrahimi // pipeline will be destroyed when helper goes out of scope
1096*b7893ccfSSadaf Ebrahimi }
1097*b7893ccfSSadaf Ebrahimi
1098*b7893ccfSSadaf Ebrahimi // Cause error by submitting command buffer that references destroyed pipeline
1099*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1100*b7893ccfSSadaf Ebrahimi "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkPipeline");
1101*b7893ccfSSadaf Ebrahimi m_commandBuffer->QueueCommandBuffer(false);
1102*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1103*b7893ccfSSadaf Ebrahimi }
1104*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidPipeline)1105*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidPipeline) {
1106*b7893ccfSSadaf Ebrahimi uint64_t fake_pipeline_handle = 0xbaad6001;
1107*b7893ccfSSadaf Ebrahimi VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
1108*b7893ccfSSadaf Ebrahimi
1109*b7893ccfSSadaf Ebrahimi // Enable VK_KHR_draw_indirect_count for KHR variants
1110*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1111*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
1112*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1113*b7893ccfSSadaf Ebrahimi }
1114*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
1115*b7893ccfSSadaf Ebrahimi bool has_khr_indirect = DeviceExtensionEnabled(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1116*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1117*b7893ccfSSadaf Ebrahimi
1118*b7893ccfSSadaf Ebrahimi // Attempt to bind an invalid Pipeline to a valid Command Buffer
1119*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindPipeline-pipeline-parameter");
1120*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
1121*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
1122*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1123*b7893ccfSSadaf Ebrahimi
1124*b7893ccfSSadaf Ebrahimi // Try each of the 6 flavors of Draw()
1125*b7893ccfSSadaf Ebrahimi m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); // Draw*() calls must be submitted within a renderpass
1126*b7893ccfSSadaf Ebrahimi
1127*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02700");
1128*b7893ccfSSadaf Ebrahimi m_commandBuffer->Draw(1, 0, 0, 0);
1129*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1130*b7893ccfSSadaf Ebrahimi
1131*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexed-None-02700");
1132*b7893ccfSSadaf Ebrahimi m_commandBuffer->DrawIndexed(1, 1, 0, 0, 0);
1133*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1134*b7893ccfSSadaf Ebrahimi
1135*b7893ccfSSadaf Ebrahimi VkBufferObj buffer;
1136*b7893ccfSSadaf Ebrahimi VkBufferCreateInfo ci = {};
1137*b7893ccfSSadaf Ebrahimi ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1138*b7893ccfSSadaf Ebrahimi ci.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
1139*b7893ccfSSadaf Ebrahimi ci.size = 1024;
1140*b7893ccfSSadaf Ebrahimi buffer.init(*m_device, ci);
1141*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirect-None-02700");
1142*b7893ccfSSadaf Ebrahimi vkCmdDrawIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 1, 0);
1143*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1144*b7893ccfSSadaf Ebrahimi
1145*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirect-None-02700");
1146*b7893ccfSSadaf Ebrahimi vkCmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 1, 0);
1147*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1148*b7893ccfSSadaf Ebrahimi
1149*b7893ccfSSadaf Ebrahimi if (has_khr_indirect) {
1150*b7893ccfSSadaf Ebrahimi auto fpCmdDrawIndirectCountKHR =
1151*b7893ccfSSadaf Ebrahimi (PFN_vkCmdDrawIndirectCountKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
1152*b7893ccfSSadaf Ebrahimi ASSERT_NE(fpCmdDrawIndirectCountKHR, nullptr);
1153*b7893ccfSSadaf Ebrahimi
1154*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-None-02700");
1155*b7893ccfSSadaf Ebrahimi // stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndirectCommand)
1156*b7893ccfSSadaf Ebrahimi fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer.handle(), 0, buffer.handle(), 512, 1, 512);
1157*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1158*b7893ccfSSadaf Ebrahimi
1159*b7893ccfSSadaf Ebrahimi auto fpCmdDrawIndexedIndirectCountKHR =
1160*b7893ccfSSadaf Ebrahimi (PFN_vkCmdDrawIndexedIndirectCountKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
1161*b7893ccfSSadaf Ebrahimi ASSERT_NE(fpCmdDrawIndexedIndirectCountKHR, nullptr);
1162*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-None-02700");
1163*b7893ccfSSadaf Ebrahimi // stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndexedIndirectCommand)
1164*b7893ccfSSadaf Ebrahimi fpCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), buffer.handle(), 0, buffer.handle(), 512, 1, 512);
1165*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1166*b7893ccfSSadaf Ebrahimi }
1167*b7893ccfSSadaf Ebrahimi
1168*b7893ccfSSadaf Ebrahimi // Also try the Dispatch variants
1169*b7893ccfSSadaf Ebrahimi vkCmdEndRenderPass(m_commandBuffer->handle()); // Compute submissions must be outside a renderpass
1170*b7893ccfSSadaf Ebrahimi
1171*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatch-None-02700");
1172*b7893ccfSSadaf Ebrahimi vkCmdDispatch(m_commandBuffer->handle(), 0, 0, 0);
1173*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1174*b7893ccfSSadaf Ebrahimi
1175*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchIndirect-None-02700");
1176*b7893ccfSSadaf Ebrahimi vkCmdDispatchIndirect(m_commandBuffer->handle(), buffer.handle(), 0);
1177*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1178*b7893ccfSSadaf Ebrahimi }
1179*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CmdDispatchExceedLimits)1180*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CmdDispatchExceedLimits) {
1181*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Compute dispatch with dimensions that exceed device limits");
1182*b7893ccfSSadaf Ebrahimi
1183*b7893ccfSSadaf Ebrahimi // Enable KHX device group extensions, if available
1184*b7893ccfSSadaf Ebrahimi if (InstanceExtensionSupported(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
1185*b7893ccfSSadaf Ebrahimi m_instance_extension_names.push_back(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME);
1186*b7893ccfSSadaf Ebrahimi }
1187*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1188*b7893ccfSSadaf Ebrahimi bool khx_dg_ext_available = false;
1189*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DEVICE_GROUP_EXTENSION_NAME)) {
1190*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_KHR_DEVICE_GROUP_EXTENSION_NAME);
1191*b7893ccfSSadaf Ebrahimi khx_dg_ext_available = true;
1192*b7893ccfSSadaf Ebrahimi }
1193*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
1194*b7893ccfSSadaf Ebrahimi
1195*b7893ccfSSadaf Ebrahimi uint32_t x_count_limit = m_device->props.limits.maxComputeWorkGroupCount[0];
1196*b7893ccfSSadaf Ebrahimi uint32_t y_count_limit = m_device->props.limits.maxComputeWorkGroupCount[1];
1197*b7893ccfSSadaf Ebrahimi uint32_t z_count_limit = m_device->props.limits.maxComputeWorkGroupCount[2];
1198*b7893ccfSSadaf Ebrahimi if (std::max({x_count_limit, y_count_limit, z_count_limit}) == UINT32_MAX) {
1199*b7893ccfSSadaf Ebrahimi printf("%s device maxComputeWorkGroupCount limit reports UINT32_MAX, test not possible, skipping.\n", kSkipPrefix);
1200*b7893ccfSSadaf Ebrahimi return;
1201*b7893ccfSSadaf Ebrahimi }
1202*b7893ccfSSadaf Ebrahimi
1203*b7893ccfSSadaf Ebrahimi uint32_t x_size_limit = m_device->props.limits.maxComputeWorkGroupSize[0];
1204*b7893ccfSSadaf Ebrahimi uint32_t y_size_limit = m_device->props.limits.maxComputeWorkGroupSize[1];
1205*b7893ccfSSadaf Ebrahimi uint32_t z_size_limit = m_device->props.limits.maxComputeWorkGroupSize[2];
1206*b7893ccfSSadaf Ebrahimi
1207*b7893ccfSSadaf Ebrahimi std::string spv_source = R"(
1208*b7893ccfSSadaf Ebrahimi OpCapability Shader
1209*b7893ccfSSadaf Ebrahimi OpMemoryModel Logical GLSL450
1210*b7893ccfSSadaf Ebrahimi OpEntryPoint GLCompute %main "main"
1211*b7893ccfSSadaf Ebrahimi OpExecutionMode %main LocalSize )";
1212*b7893ccfSSadaf Ebrahimi spv_source.append(std::to_string(x_size_limit + 1) + " " + std::to_string(y_size_limit + 1) + " " +
1213*b7893ccfSSadaf Ebrahimi std::to_string(z_size_limit + 1));
1214*b7893ccfSSadaf Ebrahimi spv_source.append(R"(
1215*b7893ccfSSadaf Ebrahimi %void = OpTypeVoid
1216*b7893ccfSSadaf Ebrahimi %3 = OpTypeFunction %void
1217*b7893ccfSSadaf Ebrahimi %main = OpFunction %void None %3
1218*b7893ccfSSadaf Ebrahimi %5 = OpLabel
1219*b7893ccfSSadaf Ebrahimi OpReturn
1220*b7893ccfSSadaf Ebrahimi OpFunctionEnd)");
1221*b7893ccfSSadaf Ebrahimi
1222*b7893ccfSSadaf Ebrahimi CreateComputePipelineHelper pipe(*this);
1223*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
1224*b7893ccfSSadaf Ebrahimi pipe.cs_.reset(new VkShaderObj(m_device, spv_source, VK_SHADER_STAGE_COMPUTE_BIT, this));
1225*b7893ccfSSadaf Ebrahimi pipe.InitState();
1226*b7893ccfSSadaf Ebrahimi
1227*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds device limit maxComputeWorkGroupSize[0]");
1228*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds device limit maxComputeWorkGroupSize[1]");
1229*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds device limit maxComputeWorkGroupSize[2]");
1230*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "features-limits-maxComputeWorkGroupInvocations");
1231*b7893ccfSSadaf Ebrahimi pipe.CreateComputePipeline();
1232*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1233*b7893ccfSSadaf Ebrahimi
1234*b7893ccfSSadaf Ebrahimi // Create a minimal compute pipeline
1235*b7893ccfSSadaf Ebrahimi x_size_limit = (x_size_limit > 1024) ? 1024 : x_size_limit;
1236*b7893ccfSSadaf Ebrahimi y_size_limit = (y_size_limit > 1024) ? 1024 : y_size_limit;
1237*b7893ccfSSadaf Ebrahimi z_size_limit = (z_size_limit > 64) ? 64 : z_size_limit;
1238*b7893ccfSSadaf Ebrahimi
1239*b7893ccfSSadaf Ebrahimi uint32_t invocations_limit = m_device->props.limits.maxComputeWorkGroupInvocations;
1240*b7893ccfSSadaf Ebrahimi x_size_limit = (x_size_limit > invocations_limit) ? invocations_limit : x_size_limit;
1241*b7893ccfSSadaf Ebrahimi invocations_limit /= x_size_limit;
1242*b7893ccfSSadaf Ebrahimi y_size_limit = (y_size_limit > invocations_limit) ? invocations_limit : y_size_limit;
1243*b7893ccfSSadaf Ebrahimi invocations_limit /= y_size_limit;
1244*b7893ccfSSadaf Ebrahimi z_size_limit = (z_size_limit > invocations_limit) ? invocations_limit : z_size_limit;
1245*b7893ccfSSadaf Ebrahimi
1246*b7893ccfSSadaf Ebrahimi char cs_text[128] = "";
1247*b7893ccfSSadaf Ebrahimi sprintf(cs_text, "#version 450\nlayout(local_size_x = %d, local_size_y = %d, local_size_z = %d) in;\nvoid main() {}\n",
1248*b7893ccfSSadaf Ebrahimi x_size_limit, y_size_limit, z_size_limit);
1249*b7893ccfSSadaf Ebrahimi
1250*b7893ccfSSadaf Ebrahimi VkShaderObj cs_obj(m_device, cs_text, VK_SHADER_STAGE_COMPUTE_BIT, this);
1251*b7893ccfSSadaf Ebrahimi pipe.cs_.reset(new VkShaderObj(m_device, cs_text, VK_SHADER_STAGE_COMPUTE_BIT, this));
1252*b7893ccfSSadaf Ebrahimi pipe.CreateComputePipeline();
1253*b7893ccfSSadaf Ebrahimi
1254*b7893ccfSSadaf Ebrahimi // Bind pipeline to command buffer
1255*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
1256*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1257*b7893ccfSSadaf Ebrahimi
1258*b7893ccfSSadaf Ebrahimi // Dispatch counts that exceed device limits
1259*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatch-groupCountX-00386");
1260*b7893ccfSSadaf Ebrahimi vkCmdDispatch(m_commandBuffer->handle(), x_count_limit + 1, y_count_limit, z_count_limit);
1261*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1262*b7893ccfSSadaf Ebrahimi
1263*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatch-groupCountY-00387");
1264*b7893ccfSSadaf Ebrahimi vkCmdDispatch(m_commandBuffer->handle(), x_count_limit, y_count_limit + 1, z_count_limit);
1265*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1266*b7893ccfSSadaf Ebrahimi
1267*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatch-groupCountZ-00388");
1268*b7893ccfSSadaf Ebrahimi vkCmdDispatch(m_commandBuffer->handle(), x_count_limit, y_count_limit, z_count_limit + 1);
1269*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1270*b7893ccfSSadaf Ebrahimi
1271*b7893ccfSSadaf Ebrahimi if (khx_dg_ext_available) {
1272*b7893ccfSSadaf Ebrahimi PFN_vkCmdDispatchBaseKHR fp_vkCmdDispatchBaseKHR =
1273*b7893ccfSSadaf Ebrahimi (PFN_vkCmdDispatchBaseKHR)vkGetInstanceProcAddr(instance(), "vkCmdDispatchBaseKHR");
1274*b7893ccfSSadaf Ebrahimi
1275*b7893ccfSSadaf Ebrahimi // Base equals or exceeds limit
1276*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-baseGroupX-00421");
1277*b7893ccfSSadaf Ebrahimi fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_count_limit, y_count_limit - 1, z_count_limit - 1, 0, 0, 0);
1278*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1279*b7893ccfSSadaf Ebrahimi
1280*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-baseGroupX-00422");
1281*b7893ccfSSadaf Ebrahimi fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_count_limit - 1, y_count_limit, z_count_limit - 1, 0, 0, 0);
1282*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1283*b7893ccfSSadaf Ebrahimi
1284*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-baseGroupZ-00423");
1285*b7893ccfSSadaf Ebrahimi fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_count_limit - 1, y_count_limit - 1, z_count_limit, 0, 0, 0);
1286*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1287*b7893ccfSSadaf Ebrahimi
1288*b7893ccfSSadaf Ebrahimi // (Base + count) exceeds limit
1289*b7893ccfSSadaf Ebrahimi uint32_t x_base = x_count_limit / 2;
1290*b7893ccfSSadaf Ebrahimi uint32_t y_base = y_count_limit / 2;
1291*b7893ccfSSadaf Ebrahimi uint32_t z_base = z_count_limit / 2;
1292*b7893ccfSSadaf Ebrahimi x_count_limit -= x_base;
1293*b7893ccfSSadaf Ebrahimi y_count_limit -= y_base;
1294*b7893ccfSSadaf Ebrahimi z_count_limit -= z_base;
1295*b7893ccfSSadaf Ebrahimi
1296*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-groupCountX-00424");
1297*b7893ccfSSadaf Ebrahimi fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_base, y_base, z_base, x_count_limit + 1, y_count_limit, z_count_limit);
1298*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1299*b7893ccfSSadaf Ebrahimi
1300*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-groupCountY-00425");
1301*b7893ccfSSadaf Ebrahimi fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_base, y_base, z_base, x_count_limit, y_count_limit + 1, z_count_limit);
1302*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1303*b7893ccfSSadaf Ebrahimi
1304*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-groupCountZ-00426");
1305*b7893ccfSSadaf Ebrahimi fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_base, y_base, z_base, x_count_limit, y_count_limit, z_count_limit + 1);
1306*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1307*b7893ccfSSadaf Ebrahimi } else {
1308*b7893ccfSSadaf Ebrahimi printf("%s KHX_DEVICE_GROUP_* extensions not supported, skipping CmdDispatchBaseKHR() tests.\n", kSkipPrefix);
1309*b7893ccfSSadaf Ebrahimi }
1310*b7893ccfSSadaf Ebrahimi }
1311*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidPipelineCreateState)1312*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidPipelineCreateState) {
1313*b7893ccfSSadaf Ebrahimi // Attempt to Create Gfx Pipeline w/o a VS
1314*b7893ccfSSadaf Ebrahimi
1315*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
1316*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1317*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitViewport());
1318*b7893ccfSSadaf Ebrahimi
1319*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1320*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1321*b7893ccfSSadaf Ebrahimi
1322*b7893ccfSSadaf Ebrahimi VkPipelineShaderStageCreateInfo shaderStage = fs.GetStageCreateInfo(); // should be: vs.GetStageCreateInfo();
1323*b7893ccfSSadaf Ebrahimi
1324*b7893ccfSSadaf Ebrahimi auto set_info = [&](CreatePipelineHelper &helper) { helper.shader_stages_ = {shaderStage}; };
1325*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1326*b7893ccfSSadaf Ebrahimi "Invalid Pipeline CreateInfo State: Vertex Shader required");
1327*b7893ccfSSadaf Ebrahimi
1328*b7893ccfSSadaf Ebrahimi // Finally, check the string validation for the shader stage pName variable. Correct the shader stage data, and bork the
1329*b7893ccfSSadaf Ebrahimi // string before calling again
1330*b7893ccfSSadaf Ebrahimi shaderStage = vs.GetStageCreateInfo();
1331*b7893ccfSSadaf Ebrahimi const uint8_t cont_char = 0xf8;
1332*b7893ccfSSadaf Ebrahimi char bad_string[] = {static_cast<char>(cont_char), static_cast<char>(cont_char), static_cast<char>(cont_char),
1333*b7893ccfSSadaf Ebrahimi static_cast<char>(cont_char)};
1334*b7893ccfSSadaf Ebrahimi shaderStage.pName = bad_string;
1335*b7893ccfSSadaf Ebrahimi
1336*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1337*b7893ccfSSadaf Ebrahimi "contains invalid characters or is badly formed");
1338*b7893ccfSSadaf Ebrahimi }
1339*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidPipelineSampleRateFeatureDisable)1340*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidPipelineSampleRateFeatureDisable) {
1341*b7893ccfSSadaf Ebrahimi // Enable sample shading in pipeline when the feature is disabled.
1342*b7893ccfSSadaf Ebrahimi // Disable sampleRateShading here
1343*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures device_features = {};
1344*b7893ccfSSadaf Ebrahimi device_features.sampleRateShading = VK_FALSE;
1345*b7893ccfSSadaf Ebrahimi
1346*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init(&device_features));
1347*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1348*b7893ccfSSadaf Ebrahimi
1349*b7893ccfSSadaf Ebrahimi // Cause the error by enabling sample shading...
1350*b7893ccfSSadaf Ebrahimi auto set_shading_enable = [](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.sampleShadingEnable = VK_TRUE; };
1351*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1352*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784");
1353*b7893ccfSSadaf Ebrahimi }
1354*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidPipelineSampleRateFeatureEnable)1355*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidPipelineSampleRateFeatureEnable) {
1356*b7893ccfSSadaf Ebrahimi // Enable sample shading in pipeline when the feature is disabled.
1357*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1358*b7893ccfSSadaf Ebrahimi
1359*b7893ccfSSadaf Ebrahimi // Require sampleRateShading here
1360*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures device_features = {};
1361*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1362*b7893ccfSSadaf Ebrahimi if (device_features.sampleRateShading == VK_FALSE) {
1363*b7893ccfSSadaf Ebrahimi printf("%s SampleRateShading feature is disabled -- skipping related checks.\n", kSkipPrefix);
1364*b7893ccfSSadaf Ebrahimi return;
1365*b7893ccfSSadaf Ebrahimi }
1366*b7893ccfSSadaf Ebrahimi
1367*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
1368*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1369*b7893ccfSSadaf Ebrahimi
1370*b7893ccfSSadaf Ebrahimi auto range_test = [this](float value, bool positive_test) {
1371*b7893ccfSSadaf Ebrahimi auto info_override = [value](CreatePipelineHelper &helper) {
1372*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_.sampleShadingEnable = VK_TRUE;
1373*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_.minSampleShading = value;
1374*b7893ccfSSadaf Ebrahimi };
1375*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, info_override, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1376*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786", positive_test);
1377*b7893ccfSSadaf Ebrahimi };
1378*b7893ccfSSadaf Ebrahimi
1379*b7893ccfSSadaf Ebrahimi range_test(NearestSmaller(0.0F), false);
1380*b7893ccfSSadaf Ebrahimi range_test(NearestGreater(1.0F), false);
1381*b7893ccfSSadaf Ebrahimi range_test(0.0F, /* positive_test= */ true);
1382*b7893ccfSSadaf Ebrahimi range_test(1.0F, /* positive_test= */ true);
1383*b7893ccfSSadaf Ebrahimi }
1384*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidPipelineSamplePNext)1385*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidPipelineSamplePNext) {
1386*b7893ccfSSadaf Ebrahimi // Enable sample shading in pipeline when the feature is disabled.
1387*b7893ccfSSadaf Ebrahimi // Check for VK_KHR_get_physical_device_properties2
1388*b7893ccfSSadaf Ebrahimi if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1389*b7893ccfSSadaf Ebrahimi m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1390*b7893ccfSSadaf Ebrahimi }
1391*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1392*b7893ccfSSadaf Ebrahimi
1393*b7893ccfSSadaf Ebrahimi // Set up the extension structs
1394*b7893ccfSSadaf Ebrahimi auto sampleLocations = chain_util::Init<VkPipelineSampleLocationsStateCreateInfoEXT>();
1395*b7893ccfSSadaf Ebrahimi sampleLocations.sampleLocationsInfo.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT;
1396*b7893ccfSSadaf Ebrahimi auto coverageToColor = chain_util::Init<VkPipelineCoverageToColorStateCreateInfoNV>();
1397*b7893ccfSSadaf Ebrahimi auto coverageModulation = chain_util::Init<VkPipelineCoverageModulationStateCreateInfoNV>();
1398*b7893ccfSSadaf Ebrahimi auto discriminatrix = [this](const char *name) { return DeviceExtensionSupported(gpu(), nullptr, name); };
1399*b7893ccfSSadaf Ebrahimi chain_util::ExtensionChain chain(discriminatrix, &m_device_extension_names);
1400*b7893ccfSSadaf Ebrahimi chain.Add(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, sampleLocations);
1401*b7893ccfSSadaf Ebrahimi chain.Add(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME, coverageToColor);
1402*b7893ccfSSadaf Ebrahimi chain.Add(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME, coverageModulation);
1403*b7893ccfSSadaf Ebrahimi const void *extension_head = chain.Head();
1404*b7893ccfSSadaf Ebrahimi
1405*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
1406*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1407*b7893ccfSSadaf Ebrahimi
1408*b7893ccfSSadaf Ebrahimi if (extension_head) {
1409*b7893ccfSSadaf Ebrahimi auto good_chain = [extension_head](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.pNext = extension_head; };
1410*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, good_chain, (VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT),
1411*b7893ccfSSadaf Ebrahimi "No error", true);
1412*b7893ccfSSadaf Ebrahimi } else {
1413*b7893ccfSSadaf Ebrahimi printf("%s Required extension not present -- skipping positive checks.\n", kSkipPrefix);
1414*b7893ccfSSadaf Ebrahimi }
1415*b7893ccfSSadaf Ebrahimi
1416*b7893ccfSSadaf Ebrahimi auto instance_ci = chain_util::Init<VkInstanceCreateInfo>();
1417*b7893ccfSSadaf Ebrahimi auto bad_chain = [&instance_ci](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.pNext = &instance_ci; };
1418*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, bad_chain, VK_DEBUG_REPORT_WARNING_BIT_EXT,
1419*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext");
1420*b7893ccfSSadaf Ebrahimi }
1421*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,VertexAttributeDivisorExtension)1422*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, VertexAttributeDivisorExtension) {
1423*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test VUIDs added with VK_EXT_vertex_attribute_divisor extension.");
1424*b7893ccfSSadaf Ebrahimi
1425*b7893ccfSSadaf Ebrahimi bool inst_ext = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1426*b7893ccfSSadaf Ebrahimi if (inst_ext) {
1427*b7893ccfSSadaf Ebrahimi m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1428*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1429*b7893ccfSSadaf Ebrahimi }
1430*b7893ccfSSadaf Ebrahimi if (inst_ext && DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
1431*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
1432*b7893ccfSSadaf Ebrahimi } else {
1433*b7893ccfSSadaf Ebrahimi printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
1434*b7893ccfSSadaf Ebrahimi return;
1435*b7893ccfSSadaf Ebrahimi }
1436*b7893ccfSSadaf Ebrahimi
1437*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vadf = {};
1438*b7893ccfSSadaf Ebrahimi vadf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
1439*b7893ccfSSadaf Ebrahimi vadf.vertexAttributeInstanceRateDivisor = VK_TRUE;
1440*b7893ccfSSadaf Ebrahimi vadf.vertexAttributeInstanceRateZeroDivisor = VK_TRUE;
1441*b7893ccfSSadaf Ebrahimi
1442*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures2 pd_features2 = {};
1443*b7893ccfSSadaf Ebrahimi pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1444*b7893ccfSSadaf Ebrahimi pd_features2.pNext = &vadf;
1445*b7893ccfSSadaf Ebrahimi
1446*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
1447*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1448*b7893ccfSSadaf Ebrahimi
1449*b7893ccfSSadaf Ebrahimi const VkPhysicalDeviceLimits &dev_limits = m_device->props.limits;
1450*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT pdvad_props = {};
1451*b7893ccfSSadaf Ebrahimi pdvad_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
1452*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceProperties2 pd_props2 = {};
1453*b7893ccfSSadaf Ebrahimi pd_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1454*b7893ccfSSadaf Ebrahimi pd_props2.pNext = &pdvad_props;
1455*b7893ccfSSadaf Ebrahimi vkGetPhysicalDeviceProperties2(gpu(), &pd_props2);
1456*b7893ccfSSadaf Ebrahimi
1457*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDivisorDescriptionEXT vibdd = {};
1458*b7893ccfSSadaf Ebrahimi VkPipelineVertexInputDivisorStateCreateInfoEXT pvids_ci = {};
1459*b7893ccfSSadaf Ebrahimi pvids_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
1460*b7893ccfSSadaf Ebrahimi pvids_ci.vertexBindingDivisorCount = 1;
1461*b7893ccfSSadaf Ebrahimi pvids_ci.pVertexBindingDivisors = &vibdd;
1462*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription vibd = {};
1463*b7893ccfSSadaf Ebrahimi vibd.stride = 12;
1464*b7893ccfSSadaf Ebrahimi vibd.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
1465*b7893ccfSSadaf Ebrahimi
1466*b7893ccfSSadaf Ebrahimi if (pdvad_props.maxVertexAttribDivisor < pvids_ci.vertexBindingDivisorCount) {
1467*b7893ccfSSadaf Ebrahimi printf("%sThis device does not support %d vertexBindingDivisors, skipping tests\n", kSkipPrefix,
1468*b7893ccfSSadaf Ebrahimi pvids_ci.vertexBindingDivisorCount);
1469*b7893ccfSSadaf Ebrahimi return;
1470*b7893ccfSSadaf Ebrahimi }
1471*b7893ccfSSadaf Ebrahimi
1472*b7893ccfSSadaf Ebrahimi using std::vector;
1473*b7893ccfSSadaf Ebrahimi struct TestCase {
1474*b7893ccfSSadaf Ebrahimi uint32_t div_binding;
1475*b7893ccfSSadaf Ebrahimi uint32_t div_divisor;
1476*b7893ccfSSadaf Ebrahimi uint32_t desc_binding;
1477*b7893ccfSSadaf Ebrahimi VkVertexInputRate desc_rate;
1478*b7893ccfSSadaf Ebrahimi vector<std::string> vuids;
1479*b7893ccfSSadaf Ebrahimi };
1480*b7893ccfSSadaf Ebrahimi
1481*b7893ccfSSadaf Ebrahimi // clang-format off
1482*b7893ccfSSadaf Ebrahimi vector<TestCase> test_cases = {
1483*b7893ccfSSadaf Ebrahimi { 0,
1484*b7893ccfSSadaf Ebrahimi 1,
1485*b7893ccfSSadaf Ebrahimi 0,
1486*b7893ccfSSadaf Ebrahimi VK_VERTEX_INPUT_RATE_VERTEX,
1487*b7893ccfSSadaf Ebrahimi {"VUID-VkVertexInputBindingDivisorDescriptionEXT-inputRate-01871"}
1488*b7893ccfSSadaf Ebrahimi },
1489*b7893ccfSSadaf Ebrahimi { dev_limits.maxVertexInputBindings + 1,
1490*b7893ccfSSadaf Ebrahimi 1,
1491*b7893ccfSSadaf Ebrahimi 0,
1492*b7893ccfSSadaf Ebrahimi VK_VERTEX_INPUT_RATE_INSTANCE,
1493*b7893ccfSSadaf Ebrahimi {"VUID-VkVertexInputBindingDivisorDescriptionEXT-binding-01869",
1494*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputBindingDivisorDescriptionEXT-inputRate-01871"}
1495*b7893ccfSSadaf Ebrahimi }
1496*b7893ccfSSadaf Ebrahimi };
1497*b7893ccfSSadaf Ebrahimi
1498*b7893ccfSSadaf Ebrahimi if (UINT32_MAX != pdvad_props.maxVertexAttribDivisor) { // Can't test overflow if maxVAD is UINT32_MAX
1499*b7893ccfSSadaf Ebrahimi test_cases.push_back(
1500*b7893ccfSSadaf Ebrahimi { 0,
1501*b7893ccfSSadaf Ebrahimi pdvad_props.maxVertexAttribDivisor + 1,
1502*b7893ccfSSadaf Ebrahimi 0,
1503*b7893ccfSSadaf Ebrahimi VK_VERTEX_INPUT_RATE_INSTANCE,
1504*b7893ccfSSadaf Ebrahimi {"VUID-VkVertexInputBindingDivisorDescriptionEXT-divisor-01870"}
1505*b7893ccfSSadaf Ebrahimi } );
1506*b7893ccfSSadaf Ebrahimi }
1507*b7893ccfSSadaf Ebrahimi // clang-format on
1508*b7893ccfSSadaf Ebrahimi
1509*b7893ccfSSadaf Ebrahimi for (const auto &test_case : test_cases) {
1510*b7893ccfSSadaf Ebrahimi const auto bad_divisor_state = [&test_case, &vibdd, &pvids_ci, &vibd](CreatePipelineHelper &helper) {
1511*b7893ccfSSadaf Ebrahimi vibdd.binding = test_case.div_binding;
1512*b7893ccfSSadaf Ebrahimi vibdd.divisor = test_case.div_divisor;
1513*b7893ccfSSadaf Ebrahimi vibd.binding = test_case.desc_binding;
1514*b7893ccfSSadaf Ebrahimi vibd.inputRate = test_case.desc_rate;
1515*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pNext = &pvids_ci;
1516*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
1517*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &vibd;
1518*b7893ccfSSadaf Ebrahimi };
1519*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, bad_divisor_state, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
1520*b7893ccfSSadaf Ebrahimi }
1521*b7893ccfSSadaf Ebrahimi }
1522*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,VertexAttributeDivisorDisabled)1523*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, VertexAttributeDivisorDisabled) {
1524*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test instance divisor feature disabled for VK_EXT_vertex_attribute_divisor extension.");
1525*b7893ccfSSadaf Ebrahimi
1526*b7893ccfSSadaf Ebrahimi bool inst_ext = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1527*b7893ccfSSadaf Ebrahimi if (inst_ext) {
1528*b7893ccfSSadaf Ebrahimi m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1529*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1530*b7893ccfSSadaf Ebrahimi }
1531*b7893ccfSSadaf Ebrahimi if (inst_ext && DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
1532*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
1533*b7893ccfSSadaf Ebrahimi } else {
1534*b7893ccfSSadaf Ebrahimi printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
1535*b7893ccfSSadaf Ebrahimi return;
1536*b7893ccfSSadaf Ebrahimi }
1537*b7893ccfSSadaf Ebrahimi
1538*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vadf = {};
1539*b7893ccfSSadaf Ebrahimi vadf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
1540*b7893ccfSSadaf Ebrahimi vadf.vertexAttributeInstanceRateDivisor = VK_FALSE;
1541*b7893ccfSSadaf Ebrahimi vadf.vertexAttributeInstanceRateZeroDivisor = VK_FALSE;
1542*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures2 pd_features2 = {};
1543*b7893ccfSSadaf Ebrahimi pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1544*b7893ccfSSadaf Ebrahimi pd_features2.pNext = &vadf;
1545*b7893ccfSSadaf Ebrahimi
1546*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
1547*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1548*b7893ccfSSadaf Ebrahimi
1549*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT pdvad_props = {};
1550*b7893ccfSSadaf Ebrahimi pdvad_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
1551*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceProperties2 pd_props2 = {};
1552*b7893ccfSSadaf Ebrahimi pd_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1553*b7893ccfSSadaf Ebrahimi pd_props2.pNext = &pdvad_props;
1554*b7893ccfSSadaf Ebrahimi vkGetPhysicalDeviceProperties2(gpu(), &pd_props2);
1555*b7893ccfSSadaf Ebrahimi
1556*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDivisorDescriptionEXT vibdd = {};
1557*b7893ccfSSadaf Ebrahimi vibdd.binding = 0;
1558*b7893ccfSSadaf Ebrahimi vibdd.divisor = 2;
1559*b7893ccfSSadaf Ebrahimi VkPipelineVertexInputDivisorStateCreateInfoEXT pvids_ci = {};
1560*b7893ccfSSadaf Ebrahimi pvids_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
1561*b7893ccfSSadaf Ebrahimi pvids_ci.vertexBindingDivisorCount = 1;
1562*b7893ccfSSadaf Ebrahimi pvids_ci.pVertexBindingDivisors = &vibdd;
1563*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription vibd = {};
1564*b7893ccfSSadaf Ebrahimi vibd.binding = vibdd.binding;
1565*b7893ccfSSadaf Ebrahimi vibd.stride = 12;
1566*b7893ccfSSadaf Ebrahimi vibd.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
1567*b7893ccfSSadaf Ebrahimi
1568*b7893ccfSSadaf Ebrahimi if (pdvad_props.maxVertexAttribDivisor < pvids_ci.vertexBindingDivisorCount) {
1569*b7893ccfSSadaf Ebrahimi printf("%sThis device does not support %d vertexBindingDivisors, skipping tests\n", kSkipPrefix,
1570*b7893ccfSSadaf Ebrahimi pvids_ci.vertexBindingDivisorCount);
1571*b7893ccfSSadaf Ebrahimi return;
1572*b7893ccfSSadaf Ebrahimi }
1573*b7893ccfSSadaf Ebrahimi
1574*b7893ccfSSadaf Ebrahimi const auto instance_rate = [&pvids_ci, &vibd](CreatePipelineHelper &helper) {
1575*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pNext = &pvids_ci;
1576*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
1577*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &vibd;
1578*b7893ccfSSadaf Ebrahimi };
1579*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, instance_rate, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1580*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputBindingDivisorDescriptionEXT-vertexAttributeInstanceRateDivisor-02229");
1581*b7893ccfSSadaf Ebrahimi }
1582*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,VertexAttributeDivisorInstanceRateZero)1583*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, VertexAttributeDivisorInstanceRateZero) {
1584*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test instanceRateZero feature of VK_EXT_vertex_attribute_divisor extension.");
1585*b7893ccfSSadaf Ebrahimi
1586*b7893ccfSSadaf Ebrahimi bool inst_ext = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1587*b7893ccfSSadaf Ebrahimi if (inst_ext) {
1588*b7893ccfSSadaf Ebrahimi m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1589*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1590*b7893ccfSSadaf Ebrahimi }
1591*b7893ccfSSadaf Ebrahimi if (inst_ext && DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
1592*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
1593*b7893ccfSSadaf Ebrahimi } else {
1594*b7893ccfSSadaf Ebrahimi printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
1595*b7893ccfSSadaf Ebrahimi return;
1596*b7893ccfSSadaf Ebrahimi }
1597*b7893ccfSSadaf Ebrahimi
1598*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vadf = {};
1599*b7893ccfSSadaf Ebrahimi vadf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
1600*b7893ccfSSadaf Ebrahimi vadf.vertexAttributeInstanceRateDivisor = VK_TRUE;
1601*b7893ccfSSadaf Ebrahimi vadf.vertexAttributeInstanceRateZeroDivisor = VK_FALSE;
1602*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures2 pd_features2 = {};
1603*b7893ccfSSadaf Ebrahimi pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1604*b7893ccfSSadaf Ebrahimi pd_features2.pNext = &vadf;
1605*b7893ccfSSadaf Ebrahimi
1606*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
1607*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1608*b7893ccfSSadaf Ebrahimi
1609*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDivisorDescriptionEXT vibdd = {};
1610*b7893ccfSSadaf Ebrahimi vibdd.binding = 0;
1611*b7893ccfSSadaf Ebrahimi vibdd.divisor = 0;
1612*b7893ccfSSadaf Ebrahimi VkPipelineVertexInputDivisorStateCreateInfoEXT pvids_ci = {};
1613*b7893ccfSSadaf Ebrahimi pvids_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
1614*b7893ccfSSadaf Ebrahimi pvids_ci.vertexBindingDivisorCount = 1;
1615*b7893ccfSSadaf Ebrahimi pvids_ci.pVertexBindingDivisors = &vibdd;
1616*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription vibd = {};
1617*b7893ccfSSadaf Ebrahimi vibd.binding = vibdd.binding;
1618*b7893ccfSSadaf Ebrahimi vibd.stride = 12;
1619*b7893ccfSSadaf Ebrahimi vibd.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
1620*b7893ccfSSadaf Ebrahimi
1621*b7893ccfSSadaf Ebrahimi const auto instance_rate = [&pvids_ci, &vibd](CreatePipelineHelper &helper) {
1622*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pNext = &pvids_ci;
1623*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
1624*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &vibd;
1625*b7893ccfSSadaf Ebrahimi };
1626*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
1627*b7893ccfSSadaf Ebrahimi *this, instance_rate, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1628*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputBindingDivisorDescriptionEXT-vertexAttributeInstanceRateZeroDivisor-02228");
1629*b7893ccfSSadaf Ebrahimi }
1630*b7893ccfSSadaf Ebrahimi
1631*b7893ccfSSadaf Ebrahimi /*// TODO : This test should be good, but needs Tess support in compiler to run
1632*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidPatchControlPoints)
1633*b7893ccfSSadaf Ebrahimi {
1634*b7893ccfSSadaf Ebrahimi // Attempt to Create Gfx Pipeline w/o a VS
1635*b7893ccfSSadaf Ebrahimi VkResult err;
1636*b7893ccfSSadaf Ebrahimi
1637*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1638*b7893ccfSSadaf Ebrahimi "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH
1639*b7893ccfSSadaf Ebrahimi primitive ");
1640*b7893ccfSSadaf Ebrahimi
1641*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
1642*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1643*b7893ccfSSadaf Ebrahimi
1644*b7893ccfSSadaf Ebrahimi VkDescriptorPoolSize ds_type_count = {};
1645*b7893ccfSSadaf Ebrahimi ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1646*b7893ccfSSadaf Ebrahimi ds_type_count.descriptorCount = 1;
1647*b7893ccfSSadaf Ebrahimi
1648*b7893ccfSSadaf Ebrahimi VkDescriptorPoolCreateInfo ds_pool_ci = {};
1649*b7893ccfSSadaf Ebrahimi ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1650*b7893ccfSSadaf Ebrahimi ds_pool_ci.pNext = NULL;
1651*b7893ccfSSadaf Ebrahimi ds_pool_ci.poolSizeCount = 1;
1652*b7893ccfSSadaf Ebrahimi ds_pool_ci.pPoolSizes = &ds_type_count;
1653*b7893ccfSSadaf Ebrahimi
1654*b7893ccfSSadaf Ebrahimi VkDescriptorPool ds_pool;
1655*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorPool(m_device->device(),
1656*b7893ccfSSadaf Ebrahimi VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool);
1657*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
1658*b7893ccfSSadaf Ebrahimi
1659*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutBinding dsl_binding = {};
1660*b7893ccfSSadaf Ebrahimi dsl_binding.binding = 0;
1661*b7893ccfSSadaf Ebrahimi dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1662*b7893ccfSSadaf Ebrahimi dsl_binding.descriptorCount = 1;
1663*b7893ccfSSadaf Ebrahimi dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
1664*b7893ccfSSadaf Ebrahimi dsl_binding.pImmutableSamplers = NULL;
1665*b7893ccfSSadaf Ebrahimi
1666*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1667*b7893ccfSSadaf Ebrahimi ds_layout_ci.sType =
1668*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1669*b7893ccfSSadaf Ebrahimi ds_layout_ci.pNext = NULL;
1670*b7893ccfSSadaf Ebrahimi ds_layout_ci.bindingCount = 1;
1671*b7893ccfSSadaf Ebrahimi ds_layout_ci.pBindings = &dsl_binding;
1672*b7893ccfSSadaf Ebrahimi
1673*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayout ds_layout;
1674*b7893ccfSSadaf Ebrahimi err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
1675*b7893ccfSSadaf Ebrahimi &ds_layout);
1676*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
1677*b7893ccfSSadaf Ebrahimi
1678*b7893ccfSSadaf Ebrahimi VkDescriptorSet descriptorSet;
1679*b7893ccfSSadaf Ebrahimi err = vkAllocateDescriptorSets(m_device->device(), ds_pool,
1680*b7893ccfSSadaf Ebrahimi VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet);
1681*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
1682*b7893ccfSSadaf Ebrahimi
1683*b7893ccfSSadaf Ebrahimi VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
1684*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.sType =
1685*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1686*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pNext = NULL;
1687*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.setLayoutCount = 1;
1688*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pSetLayouts = &ds_layout;
1689*b7893ccfSSadaf Ebrahimi
1690*b7893ccfSSadaf Ebrahimi VkPipelineLayout pipeline_layout;
1691*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
1692*b7893ccfSSadaf Ebrahimi &pipeline_layout);
1693*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
1694*b7893ccfSSadaf Ebrahimi
1695*b7893ccfSSadaf Ebrahimi VkPipelineShaderStageCreateInfo shaderStages[3];
1696*b7893ccfSSadaf Ebrahimi memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo));
1697*b7893ccfSSadaf Ebrahimi
1698*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT,
1699*b7893ccfSSadaf Ebrahimi this);
1700*b7893ccfSSadaf Ebrahimi // Just using VS txt for Tess shaders as we don't care about functionality
1701*b7893ccfSSadaf Ebrahimi VkShaderObj
1702*b7893ccfSSadaf Ebrahimi tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1703*b7893ccfSSadaf Ebrahimi this);
1704*b7893ccfSSadaf Ebrahimi VkShaderObj
1705*b7893ccfSSadaf Ebrahimi te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1706*b7893ccfSSadaf Ebrahimi this);
1707*b7893ccfSSadaf Ebrahimi
1708*b7893ccfSSadaf Ebrahimi shaderStages[0].sType =
1709*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1710*b7893ccfSSadaf Ebrahimi shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
1711*b7893ccfSSadaf Ebrahimi shaderStages[0].shader = vs.handle();
1712*b7893ccfSSadaf Ebrahimi shaderStages[1].sType =
1713*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1714*b7893ccfSSadaf Ebrahimi shaderStages[1].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
1715*b7893ccfSSadaf Ebrahimi shaderStages[1].shader = tc.handle();
1716*b7893ccfSSadaf Ebrahimi shaderStages[2].sType =
1717*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1718*b7893ccfSSadaf Ebrahimi shaderStages[2].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
1719*b7893ccfSSadaf Ebrahimi shaderStages[2].shader = te.handle();
1720*b7893ccfSSadaf Ebrahimi
1721*b7893ccfSSadaf Ebrahimi VkPipelineInputAssemblyStateCreateInfo iaCI = {};
1722*b7893ccfSSadaf Ebrahimi iaCI.sType =
1723*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
1724*b7893ccfSSadaf Ebrahimi iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
1725*b7893ccfSSadaf Ebrahimi
1726*b7893ccfSSadaf Ebrahimi VkPipelineTessellationStateCreateInfo tsCI = {};
1727*b7893ccfSSadaf Ebrahimi tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
1728*b7893ccfSSadaf Ebrahimi tsCI.patchControlPoints = 0; // This will cause an error
1729*b7893ccfSSadaf Ebrahimi
1730*b7893ccfSSadaf Ebrahimi VkGraphicsPipelineCreateInfo gp_ci = {};
1731*b7893ccfSSadaf Ebrahimi gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
1732*b7893ccfSSadaf Ebrahimi gp_ci.pNext = NULL;
1733*b7893ccfSSadaf Ebrahimi gp_ci.stageCount = 3;
1734*b7893ccfSSadaf Ebrahimi gp_ci.pStages = shaderStages;
1735*b7893ccfSSadaf Ebrahimi gp_ci.pVertexInputState = NULL;
1736*b7893ccfSSadaf Ebrahimi gp_ci.pInputAssemblyState = &iaCI;
1737*b7893ccfSSadaf Ebrahimi gp_ci.pTessellationState = &tsCI;
1738*b7893ccfSSadaf Ebrahimi gp_ci.pViewportState = NULL;
1739*b7893ccfSSadaf Ebrahimi gp_ci.pRasterizationState = NULL;
1740*b7893ccfSSadaf Ebrahimi gp_ci.pMultisampleState = NULL;
1741*b7893ccfSSadaf Ebrahimi gp_ci.pDepthStencilState = NULL;
1742*b7893ccfSSadaf Ebrahimi gp_ci.pColorBlendState = NULL;
1743*b7893ccfSSadaf Ebrahimi gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
1744*b7893ccfSSadaf Ebrahimi gp_ci.layout = pipeline_layout;
1745*b7893ccfSSadaf Ebrahimi gp_ci.renderPass = renderPass();
1746*b7893ccfSSadaf Ebrahimi
1747*b7893ccfSSadaf Ebrahimi VkPipelineCacheCreateInfo pc_ci = {};
1748*b7893ccfSSadaf Ebrahimi pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
1749*b7893ccfSSadaf Ebrahimi pc_ci.pNext = NULL;
1750*b7893ccfSSadaf Ebrahimi pc_ci.initialSize = 0;
1751*b7893ccfSSadaf Ebrahimi pc_ci.initialData = 0;
1752*b7893ccfSSadaf Ebrahimi pc_ci.maxSize = 0;
1753*b7893ccfSSadaf Ebrahimi
1754*b7893ccfSSadaf Ebrahimi VkPipeline pipeline;
1755*b7893ccfSSadaf Ebrahimi VkPipelineCache pipelineCache;
1756*b7893ccfSSadaf Ebrahimi
1757*b7893ccfSSadaf Ebrahimi err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL,
1758*b7893ccfSSadaf Ebrahimi &pipelineCache);
1759*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
1760*b7893ccfSSadaf Ebrahimi err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
1761*b7893ccfSSadaf Ebrahimi &gp_ci, NULL, &pipeline);
1762*b7893ccfSSadaf Ebrahimi
1763*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
1764*b7893ccfSSadaf Ebrahimi
1765*b7893ccfSSadaf Ebrahimi vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
1766*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
1767*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1768*b7893ccfSSadaf Ebrahimi vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
1769*b7893ccfSSadaf Ebrahimi }
1770*b7893ccfSSadaf Ebrahimi */
1771*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PSOViewportStateTests)1772*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PSOViewportStateTests) {
1773*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test VkPipelineViewportStateCreateInfo viewport and scissor count validation for non-multiViewport");
1774*b7893ccfSSadaf Ebrahimi
1775*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures features{};
1776*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init(&features));
1777*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1778*b7893ccfSSadaf Ebrahimi
1779*b7893ccfSSadaf Ebrahimi const auto break_vp_state = [](CreatePipelineHelper &helper) {
1780*b7893ccfSSadaf Ebrahimi helper.rs_state_ci_.rasterizerDiscardEnable = VK_FALSE;
1781*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pViewportState = nullptr;
1782*b7893ccfSSadaf Ebrahimi };
1783*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_vp_state, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1784*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750");
1785*b7893ccfSSadaf Ebrahimi
1786*b7893ccfSSadaf Ebrahimi VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
1787*b7893ccfSSadaf Ebrahimi VkViewport viewports[] = {viewport, viewport};
1788*b7893ccfSSadaf Ebrahimi VkRect2D scissor = {{0, 0}, {64, 64}};
1789*b7893ccfSSadaf Ebrahimi VkRect2D scissors[] = {scissor, scissor};
1790*b7893ccfSSadaf Ebrahimi
1791*b7893ccfSSadaf Ebrahimi // test viewport and scissor arrays
1792*b7893ccfSSadaf Ebrahimi using std::vector;
1793*b7893ccfSSadaf Ebrahimi struct TestCase {
1794*b7893ccfSSadaf Ebrahimi uint32_t viewport_count;
1795*b7893ccfSSadaf Ebrahimi VkViewport *viewports;
1796*b7893ccfSSadaf Ebrahimi uint32_t scissor_count;
1797*b7893ccfSSadaf Ebrahimi VkRect2D *scissors;
1798*b7893ccfSSadaf Ebrahimi
1799*b7893ccfSSadaf Ebrahimi vector<std::string> vuids;
1800*b7893ccfSSadaf Ebrahimi };
1801*b7893ccfSSadaf Ebrahimi
1802*b7893ccfSSadaf Ebrahimi vector<TestCase> test_cases = {
1803*b7893ccfSSadaf Ebrahimi {0,
1804*b7893ccfSSadaf Ebrahimi viewports,
1805*b7893ccfSSadaf Ebrahimi 1,
1806*b7893ccfSSadaf Ebrahimi scissors,
1807*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1808*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1809*b7893ccfSSadaf Ebrahimi {2,
1810*b7893ccfSSadaf Ebrahimi viewports,
1811*b7893ccfSSadaf Ebrahimi 1,
1812*b7893ccfSSadaf Ebrahimi scissors,
1813*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1814*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1815*b7893ccfSSadaf Ebrahimi {1,
1816*b7893ccfSSadaf Ebrahimi viewports,
1817*b7893ccfSSadaf Ebrahimi 0,
1818*b7893ccfSSadaf Ebrahimi scissors,
1819*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1820*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1821*b7893ccfSSadaf Ebrahimi {1,
1822*b7893ccfSSadaf Ebrahimi viewports,
1823*b7893ccfSSadaf Ebrahimi 2,
1824*b7893ccfSSadaf Ebrahimi scissors,
1825*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1826*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1827*b7893ccfSSadaf Ebrahimi {0,
1828*b7893ccfSSadaf Ebrahimi viewports,
1829*b7893ccfSSadaf Ebrahimi 0,
1830*b7893ccfSSadaf Ebrahimi scissors,
1831*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1832*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
1833*b7893ccfSSadaf Ebrahimi {2,
1834*b7893ccfSSadaf Ebrahimi viewports,
1835*b7893ccfSSadaf Ebrahimi 2,
1836*b7893ccfSSadaf Ebrahimi scissors,
1837*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1838*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
1839*b7893ccfSSadaf Ebrahimi {0,
1840*b7893ccfSSadaf Ebrahimi viewports,
1841*b7893ccfSSadaf Ebrahimi 2,
1842*b7893ccfSSadaf Ebrahimi scissors,
1843*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1844*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1845*b7893ccfSSadaf Ebrahimi {2,
1846*b7893ccfSSadaf Ebrahimi viewports,
1847*b7893ccfSSadaf Ebrahimi 0,
1848*b7893ccfSSadaf Ebrahimi scissors,
1849*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1850*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1851*b7893ccfSSadaf Ebrahimi {1, nullptr, 1, scissors, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747"}},
1852*b7893ccfSSadaf Ebrahimi {1, viewports, 1, nullptr, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
1853*b7893ccfSSadaf Ebrahimi {1,
1854*b7893ccfSSadaf Ebrahimi nullptr,
1855*b7893ccfSSadaf Ebrahimi 1,
1856*b7893ccfSSadaf Ebrahimi nullptr,
1857*b7893ccfSSadaf Ebrahimi {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747", "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
1858*b7893ccfSSadaf Ebrahimi {2,
1859*b7893ccfSSadaf Ebrahimi nullptr,
1860*b7893ccfSSadaf Ebrahimi 3,
1861*b7893ccfSSadaf Ebrahimi nullptr,
1862*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1863*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220", "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747",
1864*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
1865*b7893ccfSSadaf Ebrahimi {0,
1866*b7893ccfSSadaf Ebrahimi nullptr,
1867*b7893ccfSSadaf Ebrahimi 0,
1868*b7893ccfSSadaf Ebrahimi nullptr,
1869*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1870*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
1871*b7893ccfSSadaf Ebrahimi };
1872*b7893ccfSSadaf Ebrahimi
1873*b7893ccfSSadaf Ebrahimi for (const auto &test_case : test_cases) {
1874*b7893ccfSSadaf Ebrahimi const auto break_vp = [&test_case](CreatePipelineHelper &helper) {
1875*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.viewportCount = test_case.viewport_count;
1876*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.pViewports = test_case.viewports;
1877*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.scissorCount = test_case.scissor_count;
1878*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.pScissors = test_case.scissors;
1879*b7893ccfSSadaf Ebrahimi };
1880*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
1881*b7893ccfSSadaf Ebrahimi }
1882*b7893ccfSSadaf Ebrahimi
1883*b7893ccfSSadaf Ebrahimi vector<TestCase> dyn_test_cases = {
1884*b7893ccfSSadaf Ebrahimi {0,
1885*b7893ccfSSadaf Ebrahimi viewports,
1886*b7893ccfSSadaf Ebrahimi 1,
1887*b7893ccfSSadaf Ebrahimi scissors,
1888*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1889*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1890*b7893ccfSSadaf Ebrahimi {2,
1891*b7893ccfSSadaf Ebrahimi viewports,
1892*b7893ccfSSadaf Ebrahimi 1,
1893*b7893ccfSSadaf Ebrahimi scissors,
1894*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1895*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1896*b7893ccfSSadaf Ebrahimi {1,
1897*b7893ccfSSadaf Ebrahimi viewports,
1898*b7893ccfSSadaf Ebrahimi 0,
1899*b7893ccfSSadaf Ebrahimi scissors,
1900*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1901*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1902*b7893ccfSSadaf Ebrahimi {1,
1903*b7893ccfSSadaf Ebrahimi viewports,
1904*b7893ccfSSadaf Ebrahimi 2,
1905*b7893ccfSSadaf Ebrahimi scissors,
1906*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1907*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1908*b7893ccfSSadaf Ebrahimi {0,
1909*b7893ccfSSadaf Ebrahimi viewports,
1910*b7893ccfSSadaf Ebrahimi 0,
1911*b7893ccfSSadaf Ebrahimi scissors,
1912*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1913*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
1914*b7893ccfSSadaf Ebrahimi {2,
1915*b7893ccfSSadaf Ebrahimi viewports,
1916*b7893ccfSSadaf Ebrahimi 2,
1917*b7893ccfSSadaf Ebrahimi scissors,
1918*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1919*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
1920*b7893ccfSSadaf Ebrahimi {0,
1921*b7893ccfSSadaf Ebrahimi viewports,
1922*b7893ccfSSadaf Ebrahimi 2,
1923*b7893ccfSSadaf Ebrahimi scissors,
1924*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1925*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1926*b7893ccfSSadaf Ebrahimi {2,
1927*b7893ccfSSadaf Ebrahimi viewports,
1928*b7893ccfSSadaf Ebrahimi 0,
1929*b7893ccfSSadaf Ebrahimi scissors,
1930*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1931*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1932*b7893ccfSSadaf Ebrahimi {2,
1933*b7893ccfSSadaf Ebrahimi nullptr,
1934*b7893ccfSSadaf Ebrahimi 3,
1935*b7893ccfSSadaf Ebrahimi nullptr,
1936*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1937*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
1938*b7893ccfSSadaf Ebrahimi {0,
1939*b7893ccfSSadaf Ebrahimi nullptr,
1940*b7893ccfSSadaf Ebrahimi 0,
1941*b7893ccfSSadaf Ebrahimi nullptr,
1942*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1943*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
1944*b7893ccfSSadaf Ebrahimi };
1945*b7893ccfSSadaf Ebrahimi
1946*b7893ccfSSadaf Ebrahimi const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
1947*b7893ccfSSadaf Ebrahimi
1948*b7893ccfSSadaf Ebrahimi for (const auto &test_case : dyn_test_cases) {
1949*b7893ccfSSadaf Ebrahimi const auto break_vp = [&](CreatePipelineHelper &helper) {
1950*b7893ccfSSadaf Ebrahimi VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
1951*b7893ccfSSadaf Ebrahimi dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
1952*b7893ccfSSadaf Ebrahimi dyn_state_ci.dynamicStateCount = size(dyn_states);
1953*b7893ccfSSadaf Ebrahimi dyn_state_ci.pDynamicStates = dyn_states;
1954*b7893ccfSSadaf Ebrahimi helper.dyn_state_ci_ = dyn_state_ci;
1955*b7893ccfSSadaf Ebrahimi
1956*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.viewportCount = test_case.viewport_count;
1957*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.pViewports = test_case.viewports;
1958*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.scissorCount = test_case.scissor_count;
1959*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.pScissors = test_case.scissors;
1960*b7893ccfSSadaf Ebrahimi };
1961*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
1962*b7893ccfSSadaf Ebrahimi }
1963*b7893ccfSSadaf Ebrahimi }
1964*b7893ccfSSadaf Ebrahimi
1965*b7893ccfSSadaf Ebrahimi // Set Extension dynamic states without enabling the required Extensions.
TEST_F(VkLayerTest,ExtensionDynamicStatesSetWOExtensionEnabled)1966*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, ExtensionDynamicStatesSetWOExtensionEnabled) {
1967*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Create a graphics pipeline with Extension dynamic states without enabling the required Extensions.");
1968*b7893ccfSSadaf Ebrahimi
1969*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
1970*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1971*b7893ccfSSadaf Ebrahimi
1972*b7893ccfSSadaf Ebrahimi using std::vector;
1973*b7893ccfSSadaf Ebrahimi struct TestCase {
1974*b7893ccfSSadaf Ebrahimi uint32_t dynamic_state_count;
1975*b7893ccfSSadaf Ebrahimi VkDynamicState dynamic_state;
1976*b7893ccfSSadaf Ebrahimi
1977*b7893ccfSSadaf Ebrahimi char const *errmsg;
1978*b7893ccfSSadaf Ebrahimi };
1979*b7893ccfSSadaf Ebrahimi
1980*b7893ccfSSadaf Ebrahimi vector<TestCase> dyn_test_cases = {
1981*b7893ccfSSadaf Ebrahimi {1, VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV,
1982*b7893ccfSSadaf Ebrahimi "contains VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV, but VK_NV_clip_space_w_scaling"},
1983*b7893ccfSSadaf Ebrahimi {1, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT,
1984*b7893ccfSSadaf Ebrahimi "contains VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT, but VK_EXT_discard_rectangles"},
1985*b7893ccfSSadaf Ebrahimi {1, VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, "contains VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, but VK_EXT_sample_locations"},
1986*b7893ccfSSadaf Ebrahimi };
1987*b7893ccfSSadaf Ebrahimi
1988*b7893ccfSSadaf Ebrahimi for (const auto &test_case : dyn_test_cases) {
1989*b7893ccfSSadaf Ebrahimi VkDynamicState state[1];
1990*b7893ccfSSadaf Ebrahimi state[0] = test_case.dynamic_state;
1991*b7893ccfSSadaf Ebrahimi const auto break_vp = [&](CreatePipelineHelper &helper) {
1992*b7893ccfSSadaf Ebrahimi VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
1993*b7893ccfSSadaf Ebrahimi dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
1994*b7893ccfSSadaf Ebrahimi dyn_state_ci.dynamicStateCount = test_case.dynamic_state_count;
1995*b7893ccfSSadaf Ebrahimi dyn_state_ci.pDynamicStates = state;
1996*b7893ccfSSadaf Ebrahimi helper.dyn_state_ci_ = dyn_state_ci;
1997*b7893ccfSSadaf Ebrahimi };
1998*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.errmsg);
1999*b7893ccfSSadaf Ebrahimi }
2000*b7893ccfSSadaf Ebrahimi }
2001*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PSOViewportStateMultiViewportTests)2002*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PSOViewportStateMultiViewportTests) {
2003*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test VkPipelineViewportStateCreateInfo viewport and scissor count validation for multiViewport feature");
2004*b7893ccfSSadaf Ebrahimi
2005*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init()); // enables all supported features
2006*b7893ccfSSadaf Ebrahimi
2007*b7893ccfSSadaf Ebrahimi if (!m_device->phy().features().multiViewport) {
2008*b7893ccfSSadaf Ebrahimi printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
2009*b7893ccfSSadaf Ebrahimi return;
2010*b7893ccfSSadaf Ebrahimi }
2011*b7893ccfSSadaf Ebrahimi // at least 16 viewports supported from here on
2012*b7893ccfSSadaf Ebrahimi
2013*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2014*b7893ccfSSadaf Ebrahimi
2015*b7893ccfSSadaf Ebrahimi VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
2016*b7893ccfSSadaf Ebrahimi VkViewport viewports[] = {viewport, viewport};
2017*b7893ccfSSadaf Ebrahimi VkRect2D scissor = {{0, 0}, {64, 64}};
2018*b7893ccfSSadaf Ebrahimi VkRect2D scissors[] = {scissor, scissor};
2019*b7893ccfSSadaf Ebrahimi
2020*b7893ccfSSadaf Ebrahimi using std::vector;
2021*b7893ccfSSadaf Ebrahimi struct TestCase {
2022*b7893ccfSSadaf Ebrahimi uint32_t viewport_count;
2023*b7893ccfSSadaf Ebrahimi VkViewport *viewports;
2024*b7893ccfSSadaf Ebrahimi uint32_t scissor_count;
2025*b7893ccfSSadaf Ebrahimi VkRect2D *scissors;
2026*b7893ccfSSadaf Ebrahimi
2027*b7893ccfSSadaf Ebrahimi vector<std::string> vuids;
2028*b7893ccfSSadaf Ebrahimi };
2029*b7893ccfSSadaf Ebrahimi
2030*b7893ccfSSadaf Ebrahimi vector<TestCase> test_cases = {
2031*b7893ccfSSadaf Ebrahimi {0,
2032*b7893ccfSSadaf Ebrahimi viewports,
2033*b7893ccfSSadaf Ebrahimi 2,
2034*b7893ccfSSadaf Ebrahimi scissors,
2035*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
2036*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
2037*b7893ccfSSadaf Ebrahimi {2,
2038*b7893ccfSSadaf Ebrahimi viewports,
2039*b7893ccfSSadaf Ebrahimi 0,
2040*b7893ccfSSadaf Ebrahimi scissors,
2041*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength",
2042*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
2043*b7893ccfSSadaf Ebrahimi {0,
2044*b7893ccfSSadaf Ebrahimi viewports,
2045*b7893ccfSSadaf Ebrahimi 0,
2046*b7893ccfSSadaf Ebrahimi scissors,
2047*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
2048*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength"}},
2049*b7893ccfSSadaf Ebrahimi {2, nullptr, 2, scissors, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747"}},
2050*b7893ccfSSadaf Ebrahimi {2, viewports, 2, nullptr, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
2051*b7893ccfSSadaf Ebrahimi {2,
2052*b7893ccfSSadaf Ebrahimi nullptr,
2053*b7893ccfSSadaf Ebrahimi 2,
2054*b7893ccfSSadaf Ebrahimi nullptr,
2055*b7893ccfSSadaf Ebrahimi {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747", "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
2056*b7893ccfSSadaf Ebrahimi {0,
2057*b7893ccfSSadaf Ebrahimi nullptr,
2058*b7893ccfSSadaf Ebrahimi 0,
2059*b7893ccfSSadaf Ebrahimi nullptr,
2060*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
2061*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength"}},
2062*b7893ccfSSadaf Ebrahimi };
2063*b7893ccfSSadaf Ebrahimi
2064*b7893ccfSSadaf Ebrahimi const auto max_viewports = m_device->phy().properties().limits.maxViewports;
2065*b7893ccfSSadaf Ebrahimi const bool max_viewports_maxxed = max_viewports == std::numeric_limits<decltype(max_viewports)>::max();
2066*b7893ccfSSadaf Ebrahimi if (max_viewports_maxxed) {
2067*b7893ccfSSadaf Ebrahimi printf("%s VkPhysicalDeviceLimits::maxViewports is UINT32_MAX -- skipping part of test requiring to exceed maxViewports.\n",
2068*b7893ccfSSadaf Ebrahimi kSkipPrefix);
2069*b7893ccfSSadaf Ebrahimi } else {
2070*b7893ccfSSadaf Ebrahimi const auto too_much_viewports = max_viewports + 1;
2071*b7893ccfSSadaf Ebrahimi // avoid potentially big allocations by using only nullptr
2072*b7893ccfSSadaf Ebrahimi test_cases.push_back({too_much_viewports,
2073*b7893ccfSSadaf Ebrahimi nullptr,
2074*b7893ccfSSadaf Ebrahimi 2,
2075*b7893ccfSSadaf Ebrahimi scissors,
2076*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
2077*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220",
2078*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747"}});
2079*b7893ccfSSadaf Ebrahimi test_cases.push_back({2,
2080*b7893ccfSSadaf Ebrahimi viewports,
2081*b7893ccfSSadaf Ebrahimi too_much_viewports,
2082*b7893ccfSSadaf Ebrahimi nullptr,
2083*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219",
2084*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220",
2085*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}});
2086*b7893ccfSSadaf Ebrahimi test_cases.push_back(
2087*b7893ccfSSadaf Ebrahimi {too_much_viewports,
2088*b7893ccfSSadaf Ebrahimi nullptr,
2089*b7893ccfSSadaf Ebrahimi too_much_viewports,
2090*b7893ccfSSadaf Ebrahimi nullptr,
2091*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
2092*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219", "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747",
2093*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}});
2094*b7893ccfSSadaf Ebrahimi }
2095*b7893ccfSSadaf Ebrahimi
2096*b7893ccfSSadaf Ebrahimi for (const auto &test_case : test_cases) {
2097*b7893ccfSSadaf Ebrahimi const auto break_vp = [&test_case](CreatePipelineHelper &helper) {
2098*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.viewportCount = test_case.viewport_count;
2099*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.pViewports = test_case.viewports;
2100*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.scissorCount = test_case.scissor_count;
2101*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.pScissors = test_case.scissors;
2102*b7893ccfSSadaf Ebrahimi };
2103*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
2104*b7893ccfSSadaf Ebrahimi }
2105*b7893ccfSSadaf Ebrahimi
2106*b7893ccfSSadaf Ebrahimi vector<TestCase> dyn_test_cases = {
2107*b7893ccfSSadaf Ebrahimi {0,
2108*b7893ccfSSadaf Ebrahimi viewports,
2109*b7893ccfSSadaf Ebrahimi 2,
2110*b7893ccfSSadaf Ebrahimi scissors,
2111*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
2112*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
2113*b7893ccfSSadaf Ebrahimi {2,
2114*b7893ccfSSadaf Ebrahimi viewports,
2115*b7893ccfSSadaf Ebrahimi 0,
2116*b7893ccfSSadaf Ebrahimi scissors,
2117*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength",
2118*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
2119*b7893ccfSSadaf Ebrahimi {0,
2120*b7893ccfSSadaf Ebrahimi viewports,
2121*b7893ccfSSadaf Ebrahimi 0,
2122*b7893ccfSSadaf Ebrahimi scissors,
2123*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
2124*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength"}},
2125*b7893ccfSSadaf Ebrahimi {0,
2126*b7893ccfSSadaf Ebrahimi nullptr,
2127*b7893ccfSSadaf Ebrahimi 0,
2128*b7893ccfSSadaf Ebrahimi nullptr,
2129*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
2130*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength"}},
2131*b7893ccfSSadaf Ebrahimi };
2132*b7893ccfSSadaf Ebrahimi
2133*b7893ccfSSadaf Ebrahimi if (!max_viewports_maxxed) {
2134*b7893ccfSSadaf Ebrahimi const auto too_much_viewports = max_viewports + 1;
2135*b7893ccfSSadaf Ebrahimi // avoid potentially big allocations by using only nullptr
2136*b7893ccfSSadaf Ebrahimi dyn_test_cases.push_back({too_much_viewports,
2137*b7893ccfSSadaf Ebrahimi nullptr,
2138*b7893ccfSSadaf Ebrahimi 2,
2139*b7893ccfSSadaf Ebrahimi scissors,
2140*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
2141*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}});
2142*b7893ccfSSadaf Ebrahimi dyn_test_cases.push_back({2,
2143*b7893ccfSSadaf Ebrahimi viewports,
2144*b7893ccfSSadaf Ebrahimi too_much_viewports,
2145*b7893ccfSSadaf Ebrahimi nullptr,
2146*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219",
2147*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}});
2148*b7893ccfSSadaf Ebrahimi dyn_test_cases.push_back({too_much_viewports,
2149*b7893ccfSSadaf Ebrahimi nullptr,
2150*b7893ccfSSadaf Ebrahimi too_much_viewports,
2151*b7893ccfSSadaf Ebrahimi nullptr,
2152*b7893ccfSSadaf Ebrahimi {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
2153*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219"}});
2154*b7893ccfSSadaf Ebrahimi }
2155*b7893ccfSSadaf Ebrahimi
2156*b7893ccfSSadaf Ebrahimi const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
2157*b7893ccfSSadaf Ebrahimi
2158*b7893ccfSSadaf Ebrahimi for (const auto &test_case : dyn_test_cases) {
2159*b7893ccfSSadaf Ebrahimi const auto break_vp = [&](CreatePipelineHelper &helper) {
2160*b7893ccfSSadaf Ebrahimi VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
2161*b7893ccfSSadaf Ebrahimi dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
2162*b7893ccfSSadaf Ebrahimi dyn_state_ci.dynamicStateCount = size(dyn_states);
2163*b7893ccfSSadaf Ebrahimi dyn_state_ci.pDynamicStates = dyn_states;
2164*b7893ccfSSadaf Ebrahimi helper.dyn_state_ci_ = dyn_state_ci;
2165*b7893ccfSSadaf Ebrahimi
2166*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.viewportCount = test_case.viewport_count;
2167*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.pViewports = test_case.viewports;
2168*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.scissorCount = test_case.scissor_count;
2169*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.pScissors = test_case.scissors;
2170*b7893ccfSSadaf Ebrahimi };
2171*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
2172*b7893ccfSSadaf Ebrahimi }
2173*b7893ccfSSadaf Ebrahimi }
2174*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,DynViewportAndScissorUndefinedDrawState)2175*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, DynViewportAndScissorUndefinedDrawState) {
2176*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test viewport and scissor dynamic state that is not set before draw");
2177*b7893ccfSSadaf Ebrahimi
2178*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2179*b7893ccfSSadaf Ebrahimi
2180*b7893ccfSSadaf Ebrahimi // TODO: should also test on !multiViewport
2181*b7893ccfSSadaf Ebrahimi if (!m_device->phy().features().multiViewport) {
2182*b7893ccfSSadaf Ebrahimi printf("%s Device does not support multiple viewports/scissors; skipped.\n", kSkipPrefix);
2183*b7893ccfSSadaf Ebrahimi return;
2184*b7893ccfSSadaf Ebrahimi }
2185*b7893ccfSSadaf Ebrahimi
2186*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitViewport());
2187*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2188*b7893ccfSSadaf Ebrahimi
2189*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2190*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2191*b7893ccfSSadaf Ebrahimi
2192*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pipeline_layout(m_device);
2193*b7893ccfSSadaf Ebrahimi
2194*b7893ccfSSadaf Ebrahimi VkPipelineObj pipeline_dyn_vp(m_device);
2195*b7893ccfSSadaf Ebrahimi pipeline_dyn_vp.AddShader(&vs);
2196*b7893ccfSSadaf Ebrahimi pipeline_dyn_vp.AddShader(&fs);
2197*b7893ccfSSadaf Ebrahimi pipeline_dyn_vp.AddDefaultColorAttachment();
2198*b7893ccfSSadaf Ebrahimi pipeline_dyn_vp.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT);
2199*b7893ccfSSadaf Ebrahimi pipeline_dyn_vp.SetScissor(m_scissors);
2200*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(pipeline_dyn_vp.CreateVKPipeline(pipeline_layout.handle(), m_renderPass));
2201*b7893ccfSSadaf Ebrahimi
2202*b7893ccfSSadaf Ebrahimi VkPipelineObj pipeline_dyn_sc(m_device);
2203*b7893ccfSSadaf Ebrahimi pipeline_dyn_sc.AddShader(&vs);
2204*b7893ccfSSadaf Ebrahimi pipeline_dyn_sc.AddShader(&fs);
2205*b7893ccfSSadaf Ebrahimi pipeline_dyn_sc.AddDefaultColorAttachment();
2206*b7893ccfSSadaf Ebrahimi pipeline_dyn_sc.SetViewport(m_viewports);
2207*b7893ccfSSadaf Ebrahimi pipeline_dyn_sc.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR);
2208*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(pipeline_dyn_sc.CreateVKPipeline(pipeline_layout.handle(), m_renderPass));
2209*b7893ccfSSadaf Ebrahimi
2210*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
2211*b7893ccfSSadaf Ebrahimi m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2212*b7893ccfSSadaf Ebrahimi
2213*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2214*b7893ccfSSadaf Ebrahimi "Dynamic viewport(s) 0 are used by pipeline state object, ");
2215*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_dyn_vp.handle());
2216*b7893ccfSSadaf Ebrahimi vkCmdSetViewport(m_commandBuffer->handle(), 1, 1,
2217*b7893ccfSSadaf Ebrahimi &m_viewports[0]); // Forgetting to set needed 0th viewport (PSO viewportCount == 1)
2218*b7893ccfSSadaf Ebrahimi m_commandBuffer->Draw(1, 0, 0, 0);
2219*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2220*b7893ccfSSadaf Ebrahimi
2221*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by pipeline state object, ");
2222*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_dyn_sc.handle());
2223*b7893ccfSSadaf Ebrahimi vkCmdSetScissor(m_commandBuffer->handle(), 1, 1,
2224*b7893ccfSSadaf Ebrahimi &m_scissors[0]); // Forgetting to set needed 0th scissor (PSO scissorCount == 1)
2225*b7893ccfSSadaf Ebrahimi m_commandBuffer->Draw(1, 0, 0, 0);
2226*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2227*b7893ccfSSadaf Ebrahimi
2228*b7893ccfSSadaf Ebrahimi m_commandBuffer->EndRenderPass();
2229*b7893ccfSSadaf Ebrahimi m_commandBuffer->end();
2230*b7893ccfSSadaf Ebrahimi }
2231*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,PSOLineWidthInvalid)2232*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, PSOLineWidthInvalid) {
2233*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test non-1.0 lineWidth errors when pipeline is created and in vkCmdSetLineWidth");
2234*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures features{};
2235*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init(&features));
2236*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2237*b7893ccfSSadaf Ebrahimi
2238*b7893ccfSSadaf Ebrahimi const std::vector<float> test_cases = {-1.0f, 0.0f, NearestSmaller(1.0f), NearestGreater(1.0f), NAN};
2239*b7893ccfSSadaf Ebrahimi
2240*b7893ccfSSadaf Ebrahimi // test VkPipelineRasterizationStateCreateInfo::lineWidth
2241*b7893ccfSSadaf Ebrahimi for (const auto test_case : test_cases) {
2242*b7893ccfSSadaf Ebrahimi const auto set_lineWidth = [&](CreatePipelineHelper &helper) { helper.rs_state_ci_.lineWidth = test_case; };
2243*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_lineWidth, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2244*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00749");
2245*b7893ccfSSadaf Ebrahimi }
2246*b7893ccfSSadaf Ebrahimi
2247*b7893ccfSSadaf Ebrahimi // test vkCmdSetLineWidth
2248*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
2249*b7893ccfSSadaf Ebrahimi
2250*b7893ccfSSadaf Ebrahimi for (const auto test_case : test_cases) {
2251*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetLineWidth-lineWidth-00788");
2252*b7893ccfSSadaf Ebrahimi vkCmdSetLineWidth(m_commandBuffer->handle(), test_case);
2253*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2254*b7893ccfSSadaf Ebrahimi }
2255*b7893ccfSSadaf Ebrahimi }
2256*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,VUID_VkVertexInputBindingDescription_binding_00618)2257*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, VUID_VkVertexInputBindingDescription_binding_00618) {
2258*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2259*b7893ccfSSadaf Ebrahimi "Test VUID-VkVertexInputBindingDescription-binding-00618: binding must be less than "
2260*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceLimits::maxVertexInputBindings");
2261*b7893ccfSSadaf Ebrahimi
2262*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2263*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2264*b7893ccfSSadaf Ebrahimi
2265*b7893ccfSSadaf Ebrahimi // Test when binding is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings.
2266*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription vertex_input_binding_description{};
2267*b7893ccfSSadaf Ebrahimi vertex_input_binding_description.binding = m_device->props.limits.maxVertexInputBindings;
2268*b7893ccfSSadaf Ebrahimi
2269*b7893ccfSSadaf Ebrahimi const auto set_binding = [&](CreatePipelineHelper &helper) {
2270*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &vertex_input_binding_description;
2271*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
2272*b7893ccfSSadaf Ebrahimi };
2273*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_binding, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2274*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputBindingDescription-binding-00618");
2275*b7893ccfSSadaf Ebrahimi }
2276*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,VUID_VkVertexInputBindingDescription_stride_00619)2277*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, VUID_VkVertexInputBindingDescription_stride_00619) {
2278*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2279*b7893ccfSSadaf Ebrahimi "Test VUID-VkVertexInputBindingDescription-stride-00619: stride must be less than or equal to "
2280*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceLimits::maxVertexInputBindingStride");
2281*b7893ccfSSadaf Ebrahimi
2282*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2283*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2284*b7893ccfSSadaf Ebrahimi
2285*b7893ccfSSadaf Ebrahimi // Test when stride is greater than VkPhysicalDeviceLimits::maxVertexInputBindingStride.
2286*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription vertex_input_binding_description{};
2287*b7893ccfSSadaf Ebrahimi vertex_input_binding_description.stride = m_device->props.limits.maxVertexInputBindingStride + 1;
2288*b7893ccfSSadaf Ebrahimi
2289*b7893ccfSSadaf Ebrahimi const auto set_binding = [&](CreatePipelineHelper &helper) {
2290*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &vertex_input_binding_description;
2291*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
2292*b7893ccfSSadaf Ebrahimi };
2293*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_binding, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2294*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputBindingDescription-stride-00619");
2295*b7893ccfSSadaf Ebrahimi }
2296*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,VUID_VkVertexInputAttributeDescription_location_00620)2297*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, VUID_VkVertexInputAttributeDescription_location_00620) {
2298*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2299*b7893ccfSSadaf Ebrahimi "Test VUID-VkVertexInputAttributeDescription-location-00620: location must be less than "
2300*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceLimits::maxVertexInputAttributes");
2301*b7893ccfSSadaf Ebrahimi
2302*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2303*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2304*b7893ccfSSadaf Ebrahimi
2305*b7893ccfSSadaf Ebrahimi // Test when location is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes.
2306*b7893ccfSSadaf Ebrahimi VkVertexInputAttributeDescription vertex_input_attribute_description{};
2307*b7893ccfSSadaf Ebrahimi vertex_input_attribute_description.location = m_device->props.limits.maxVertexInputAttributes;
2308*b7893ccfSSadaf Ebrahimi
2309*b7893ccfSSadaf Ebrahimi const auto set_attribute = [&](CreatePipelineHelper &helper) {
2310*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = &vertex_input_attribute_description;
2311*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = 1;
2312*b7893ccfSSadaf Ebrahimi };
2313*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_attribute, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2314*b7893ccfSSadaf Ebrahimi vector<string>{"VUID-VkVertexInputAttributeDescription-location-00620",
2315*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-binding-00615"});
2316*b7893ccfSSadaf Ebrahimi }
2317*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,VUID_VkVertexInputAttributeDescription_binding_00621)2318*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, VUID_VkVertexInputAttributeDescription_binding_00621) {
2319*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2320*b7893ccfSSadaf Ebrahimi "Test VUID-VkVertexInputAttributeDescription-binding-00621: binding must be less than "
2321*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceLimits::maxVertexInputBindings");
2322*b7893ccfSSadaf Ebrahimi
2323*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2324*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2325*b7893ccfSSadaf Ebrahimi
2326*b7893ccfSSadaf Ebrahimi // Test when binding is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings.
2327*b7893ccfSSadaf Ebrahimi VkVertexInputAttributeDescription vertex_input_attribute_description{};
2328*b7893ccfSSadaf Ebrahimi vertex_input_attribute_description.binding = m_device->props.limits.maxVertexInputBindings;
2329*b7893ccfSSadaf Ebrahimi
2330*b7893ccfSSadaf Ebrahimi const auto set_attribute = [&](CreatePipelineHelper &helper) {
2331*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = &vertex_input_attribute_description;
2332*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = 1;
2333*b7893ccfSSadaf Ebrahimi };
2334*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_attribute, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2335*b7893ccfSSadaf Ebrahimi vector<string>{"VUID-VkVertexInputAttributeDescription-binding-00621",
2336*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-binding-00615"});
2337*b7893ccfSSadaf Ebrahimi }
2338*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,VUID_VkVertexInputAttributeDescription_offset_00622)2339*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, VUID_VkVertexInputAttributeDescription_offset_00622) {
2340*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2341*b7893ccfSSadaf Ebrahimi "Test VUID-VkVertexInputAttributeDescription-offset-00622: offset must be less than or equal to "
2342*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceLimits::maxVertexInputAttributeOffset");
2343*b7893ccfSSadaf Ebrahimi
2344*b7893ccfSSadaf Ebrahimi EnableDeviceProfileLayer();
2345*b7893ccfSSadaf Ebrahimi
2346*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2347*b7893ccfSSadaf Ebrahimi
2348*b7893ccfSSadaf Ebrahimi uint32_t maxVertexInputAttributeOffset = 0;
2349*b7893ccfSSadaf Ebrahimi {
2350*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceProperties device_props = {};
2351*b7893ccfSSadaf Ebrahimi vkGetPhysicalDeviceProperties(gpu(), &device_props);
2352*b7893ccfSSadaf Ebrahimi maxVertexInputAttributeOffset = device_props.limits.maxVertexInputAttributeOffset;
2353*b7893ccfSSadaf Ebrahimi if (maxVertexInputAttributeOffset == 0xFFFFFFFF) {
2354*b7893ccfSSadaf Ebrahimi // Attempt to artificially lower maximum offset
2355*b7893ccfSSadaf Ebrahimi PFN_vkSetPhysicalDeviceLimitsEXT fpvkSetPhysicalDeviceLimitsEXT =
2356*b7893ccfSSadaf Ebrahimi (PFN_vkSetPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceLimitsEXT");
2357*b7893ccfSSadaf Ebrahimi if (!fpvkSetPhysicalDeviceLimitsEXT) {
2358*b7893ccfSSadaf Ebrahimi printf("%s All offsets are valid & device_profile_api not found; skipped.\n", kSkipPrefix);
2359*b7893ccfSSadaf Ebrahimi return;
2360*b7893ccfSSadaf Ebrahimi }
2361*b7893ccfSSadaf Ebrahimi device_props.limits.maxVertexInputAttributeOffset = device_props.limits.maxVertexInputBindingStride - 2;
2362*b7893ccfSSadaf Ebrahimi fpvkSetPhysicalDeviceLimitsEXT(gpu(), &device_props.limits);
2363*b7893ccfSSadaf Ebrahimi maxVertexInputAttributeOffset = device_props.limits.maxVertexInputAttributeOffset;
2364*b7893ccfSSadaf Ebrahimi }
2365*b7893ccfSSadaf Ebrahimi }
2366*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
2367*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2368*b7893ccfSSadaf Ebrahimi
2369*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription vertex_input_binding_description{};
2370*b7893ccfSSadaf Ebrahimi vertex_input_binding_description.binding = 0;
2371*b7893ccfSSadaf Ebrahimi vertex_input_binding_description.stride = m_device->props.limits.maxVertexInputBindingStride;
2372*b7893ccfSSadaf Ebrahimi vertex_input_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2373*b7893ccfSSadaf Ebrahimi // Test when offset is greater than maximum.
2374*b7893ccfSSadaf Ebrahimi VkVertexInputAttributeDescription vertex_input_attribute_description{};
2375*b7893ccfSSadaf Ebrahimi vertex_input_attribute_description.format = VK_FORMAT_R8_UNORM;
2376*b7893ccfSSadaf Ebrahimi vertex_input_attribute_description.offset = maxVertexInputAttributeOffset + 1;
2377*b7893ccfSSadaf Ebrahimi
2378*b7893ccfSSadaf Ebrahimi const auto set_attribute = [&](CreatePipelineHelper &helper) {
2379*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &vertex_input_binding_description;
2380*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
2381*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = &vertex_input_attribute_description;
2382*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = 1;
2383*b7893ccfSSadaf Ebrahimi };
2384*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_attribute, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2385*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputAttributeDescription-offset-00622");
2386*b7893ccfSSadaf Ebrahimi }
2387*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,NumSamplesMismatch)2388*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, NumSamplesMismatch) {
2389*b7893ccfSSadaf Ebrahimi // Create CommandBuffer where MSAA samples doesn't match RenderPass
2390*b7893ccfSSadaf Ebrahimi // sampleCount
2391*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! ");
2392*b7893ccfSSadaf Ebrahimi
2393*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2394*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2395*b7893ccfSSadaf Ebrahimi
2396*b7893ccfSSadaf Ebrahimi OneOffDescriptorSet descriptor_set(m_device, {
2397*b7893ccfSSadaf Ebrahimi {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
2398*b7893ccfSSadaf Ebrahimi });
2399*b7893ccfSSadaf Ebrahimi
2400*b7893ccfSSadaf Ebrahimi VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
2401*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
2402*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.pNext = NULL;
2403*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
2404*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.sampleShadingEnable = 0;
2405*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.minSampleShading = 1.0;
2406*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.pSampleMask = NULL;
2407*b7893ccfSSadaf Ebrahimi
2408*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pipeline_layout(m_device, {&descriptor_set.layout_});
2409*b7893ccfSSadaf Ebrahimi
2410*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2411*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
2412*b7893ccfSSadaf Ebrahimi // but add it to be able to run on more devices
2413*b7893ccfSSadaf Ebrahimi VkPipelineObj pipe(m_device);
2414*b7893ccfSSadaf Ebrahimi pipe.AddShader(&vs);
2415*b7893ccfSSadaf Ebrahimi pipe.AddShader(&fs);
2416*b7893ccfSSadaf Ebrahimi pipe.AddDefaultColorAttachment();
2417*b7893ccfSSadaf Ebrahimi pipe.SetMSAA(&pipe_ms_state_ci);
2418*b7893ccfSSadaf Ebrahimi
2419*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetUnexpectedError("VUID-VkGraphicsPipelineCreateInfo-subpass-00757");
2420*b7893ccfSSadaf Ebrahimi pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
2421*b7893ccfSSadaf Ebrahimi
2422*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
2423*b7893ccfSSadaf Ebrahimi m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2424*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
2425*b7893ccfSSadaf Ebrahimi
2426*b7893ccfSSadaf Ebrahimi VkViewport viewport = {0, 0, 16, 16, 0, 1};
2427*b7893ccfSSadaf Ebrahimi vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
2428*b7893ccfSSadaf Ebrahimi VkRect2D scissor = {{0, 0}, {16, 16}};
2429*b7893ccfSSadaf Ebrahimi vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
2430*b7893ccfSSadaf Ebrahimi
2431*b7893ccfSSadaf Ebrahimi // Render triangle (the error should trigger on the attempt to draw).
2432*b7893ccfSSadaf Ebrahimi m_commandBuffer->Draw(3, 1, 0, 0);
2433*b7893ccfSSadaf Ebrahimi
2434*b7893ccfSSadaf Ebrahimi // Finalize recording of the command buffer
2435*b7893ccfSSadaf Ebrahimi m_commandBuffer->EndRenderPass();
2436*b7893ccfSSadaf Ebrahimi m_commandBuffer->end();
2437*b7893ccfSSadaf Ebrahimi
2438*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2439*b7893ccfSSadaf Ebrahimi }
2440*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,NumBlendAttachMismatch)2441*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, NumBlendAttachMismatch) {
2442*b7893ccfSSadaf Ebrahimi // Create Pipeline where the number of blend attachments doesn't match the
2443*b7893ccfSSadaf Ebrahimi // number of color attachments. In this case, we don't add any color
2444*b7893ccfSSadaf Ebrahimi // blend attachments even though we have a color attachment.
2445*b7893ccfSSadaf Ebrahimi
2446*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2447*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2448*b7893ccfSSadaf Ebrahimi
2449*b7893ccfSSadaf Ebrahimi VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
2450*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
2451*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.pNext = NULL;
2452*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
2453*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.sampleShadingEnable = 0;
2454*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.minSampleShading = 1.0;
2455*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.pSampleMask = NULL;
2456*b7893ccfSSadaf Ebrahimi
2457*b7893ccfSSadaf Ebrahimi const auto set_MSAA = [&](CreatePipelineHelper &helper) {
2458*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_ = pipe_ms_state_ci;
2459*b7893ccfSSadaf Ebrahimi helper.cb_ci_.attachmentCount = 0;
2460*b7893ccfSSadaf Ebrahimi };
2461*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_MSAA, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2462*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-attachmentCount-00746");
2463*b7893ccfSSadaf Ebrahimi }
2464*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CmdClearAttachmentTests)2465*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CmdClearAttachmentTests) {
2466*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Various tests for validating usage of vkCmdClearAttachments");
2467*b7893ccfSSadaf Ebrahimi
2468*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2469*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2470*b7893ccfSSadaf Ebrahimi
2471*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
2472*b7893ccfSSadaf Ebrahimi m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2473*b7893ccfSSadaf Ebrahimi
2474*b7893ccfSSadaf Ebrahimi // Main thing we care about for this test is that the VkImage obj we're
2475*b7893ccfSSadaf Ebrahimi // clearing matches Color Attachment of FB
2476*b7893ccfSSadaf Ebrahimi // Also pass down other dummy params to keep driver and paramchecker happy
2477*b7893ccfSSadaf Ebrahimi VkClearAttachment color_attachment;
2478*b7893ccfSSadaf Ebrahimi color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2479*b7893ccfSSadaf Ebrahimi color_attachment.clearValue.color.float32[0] = 1.0;
2480*b7893ccfSSadaf Ebrahimi color_attachment.clearValue.color.float32[1] = 1.0;
2481*b7893ccfSSadaf Ebrahimi color_attachment.clearValue.color.float32[2] = 1.0;
2482*b7893ccfSSadaf Ebrahimi color_attachment.clearValue.color.float32[3] = 1.0;
2483*b7893ccfSSadaf Ebrahimi color_attachment.colorAttachment = 0;
2484*b7893ccfSSadaf Ebrahimi VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
2485*b7893ccfSSadaf Ebrahimi
2486*b7893ccfSSadaf Ebrahimi // Call for full-sized FB Color attachment prior to issuing a Draw
2487*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
2488*b7893ccfSSadaf Ebrahimi "UNASSIGNED-CoreValidation-DrawState-ClearCmdBeforeDraw");
2489*b7893ccfSSadaf Ebrahimi vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
2490*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2491*b7893ccfSSadaf Ebrahimi
2492*b7893ccfSSadaf Ebrahimi clear_rect.rect.extent.width = renderPassBeginInfo().renderArea.extent.width + 4;
2493*b7893ccfSSadaf Ebrahimi clear_rect.rect.extent.height = clear_rect.rect.extent.height / 2;
2494*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-pRects-00016");
2495*b7893ccfSSadaf Ebrahimi vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
2496*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2497*b7893ccfSSadaf Ebrahimi
2498*b7893ccfSSadaf Ebrahimi // baseLayer >= view layers
2499*b7893ccfSSadaf Ebrahimi clear_rect.rect.extent.width = (uint32_t)m_width;
2500*b7893ccfSSadaf Ebrahimi clear_rect.baseArrayLayer = 1;
2501*b7893ccfSSadaf Ebrahimi clear_rect.layerCount = 1;
2502*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-pRects-00017");
2503*b7893ccfSSadaf Ebrahimi vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
2504*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2505*b7893ccfSSadaf Ebrahimi
2506*b7893ccfSSadaf Ebrahimi // baseLayer + layerCount > view layers
2507*b7893ccfSSadaf Ebrahimi clear_rect.rect.extent.width = (uint32_t)m_width;
2508*b7893ccfSSadaf Ebrahimi clear_rect.baseArrayLayer = 0;
2509*b7893ccfSSadaf Ebrahimi clear_rect.layerCount = 2;
2510*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-pRects-00017");
2511*b7893ccfSSadaf Ebrahimi vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
2512*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2513*b7893ccfSSadaf Ebrahimi
2514*b7893ccfSSadaf Ebrahimi m_commandBuffer->EndRenderPass();
2515*b7893ccfSSadaf Ebrahimi m_commandBuffer->end();
2516*b7893ccfSSadaf Ebrahimi }
2517*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,VtxBufferBadIndex)2518*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, VtxBufferBadIndex) {
2519*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
2520*b7893ccfSSadaf Ebrahimi "UNASSIGNED-CoreValidation-DrawState-VtxIndexOutOfBounds");
2521*b7893ccfSSadaf Ebrahimi
2522*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2523*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitViewport());
2524*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2525*b7893ccfSSadaf Ebrahimi
2526*b7893ccfSSadaf Ebrahimi VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
2527*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
2528*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.pNext = NULL;
2529*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
2530*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.sampleShadingEnable = 0;
2531*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.minSampleShading = 1.0;
2532*b7893ccfSSadaf Ebrahimi pipe_ms_state_ci.pSampleMask = NULL;
2533*b7893ccfSSadaf Ebrahimi
2534*b7893ccfSSadaf Ebrahimi CreatePipelineHelper pipe(*this);
2535*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
2536*b7893ccfSSadaf Ebrahimi pipe.pipe_ms_state_ci_ = pipe_ms_state_ci;
2537*b7893ccfSSadaf Ebrahimi pipe.InitState();
2538*b7893ccfSSadaf Ebrahimi pipe.CreateGraphicsPipeline();
2539*b7893ccfSSadaf Ebrahimi
2540*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
2541*b7893ccfSSadaf Ebrahimi m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2542*b7893ccfSSadaf Ebrahimi vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
2543*b7893ccfSSadaf Ebrahimi // Don't care about actual data, just need to get to draw to flag error
2544*b7893ccfSSadaf Ebrahimi const float vbo_data[3] = {1.f, 0.f, 1.f};
2545*b7893ccfSSadaf Ebrahimi VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
2546*b7893ccfSSadaf Ebrahimi m_commandBuffer->BindVertexBuffer(&vbo, (VkDeviceSize)0, 1); // VBO idx 1, but no VBO in PSO
2547*b7893ccfSSadaf Ebrahimi m_commandBuffer->Draw(1, 0, 0, 0);
2548*b7893ccfSSadaf Ebrahimi
2549*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2550*b7893ccfSSadaf Ebrahimi
2551*b7893ccfSSadaf Ebrahimi m_commandBuffer->EndRenderPass();
2552*b7893ccfSSadaf Ebrahimi m_commandBuffer->end();
2553*b7893ccfSSadaf Ebrahimi }
2554*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidVertexBindingDescriptions)2555*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidVertexBindingDescriptions) {
2556*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2557*b7893ccfSSadaf Ebrahimi "Attempt to create a graphics pipeline where:"
2558*b7893ccfSSadaf Ebrahimi "1) count of vertex bindings exceeds device's maxVertexInputBindings limit"
2559*b7893ccfSSadaf Ebrahimi "2) requested bindings include a duplicate binding value");
2560*b7893ccfSSadaf Ebrahimi
2561*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2562*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2563*b7893ccfSSadaf Ebrahimi
2564*b7893ccfSSadaf Ebrahimi const uint32_t binding_count = m_device->props.limits.maxVertexInputBindings + 1;
2565*b7893ccfSSadaf Ebrahimi
2566*b7893ccfSSadaf Ebrahimi std::vector<VkVertexInputBindingDescription> input_bindings(binding_count);
2567*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < binding_count; ++i) {
2568*b7893ccfSSadaf Ebrahimi input_bindings[i].binding = i;
2569*b7893ccfSSadaf Ebrahimi input_bindings[i].stride = 4;
2570*b7893ccfSSadaf Ebrahimi input_bindings[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2571*b7893ccfSSadaf Ebrahimi }
2572*b7893ccfSSadaf Ebrahimi // Let the last binding description use same binding as the first one
2573*b7893ccfSSadaf Ebrahimi input_bindings[binding_count - 1].binding = 0;
2574*b7893ccfSSadaf Ebrahimi
2575*b7893ccfSSadaf Ebrahimi VkVertexInputAttributeDescription input_attrib;
2576*b7893ccfSSadaf Ebrahimi input_attrib.binding = 0;
2577*b7893ccfSSadaf Ebrahimi input_attrib.location = 0;
2578*b7893ccfSSadaf Ebrahimi input_attrib.format = VK_FORMAT_R32G32B32_SFLOAT;
2579*b7893ccfSSadaf Ebrahimi input_attrib.offset = 0;
2580*b7893ccfSSadaf Ebrahimi
2581*b7893ccfSSadaf Ebrahimi const auto set_Info = [&](CreatePipelineHelper &helper) {
2582*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = input_bindings.data();
2583*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = binding_count;
2584*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = &input_attrib;
2585*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = 1;
2586*b7893ccfSSadaf Ebrahimi };
2587*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
2588*b7893ccfSSadaf Ebrahimi *this, set_Info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2589*b7893ccfSSadaf Ebrahimi vector<string>{"VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613",
2590*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-00616"});
2591*b7893ccfSSadaf Ebrahimi }
2592*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidVertexAttributeDescriptions)2593*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidVertexAttributeDescriptions) {
2594*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2595*b7893ccfSSadaf Ebrahimi "Attempt to create a graphics pipeline where:"
2596*b7893ccfSSadaf Ebrahimi "1) count of vertex attributes exceeds device's maxVertexInputAttributes limit"
2597*b7893ccfSSadaf Ebrahimi "2) requested location include a duplicate location value"
2598*b7893ccfSSadaf Ebrahimi "3) binding used by one attribute is not defined by a binding description");
2599*b7893ccfSSadaf Ebrahimi
2600*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2601*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2602*b7893ccfSSadaf Ebrahimi
2603*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription input_binding;
2604*b7893ccfSSadaf Ebrahimi input_binding.binding = 0;
2605*b7893ccfSSadaf Ebrahimi input_binding.stride = 4;
2606*b7893ccfSSadaf Ebrahimi input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2607*b7893ccfSSadaf Ebrahimi
2608*b7893ccfSSadaf Ebrahimi const uint32_t attribute_count = m_device->props.limits.maxVertexInputAttributes + 1;
2609*b7893ccfSSadaf Ebrahimi std::vector<VkVertexInputAttributeDescription> input_attribs(attribute_count);
2610*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < attribute_count; ++i) {
2611*b7893ccfSSadaf Ebrahimi input_attribs[i].binding = 0;
2612*b7893ccfSSadaf Ebrahimi input_attribs[i].location = i;
2613*b7893ccfSSadaf Ebrahimi input_attribs[i].format = VK_FORMAT_R32G32B32_SFLOAT;
2614*b7893ccfSSadaf Ebrahimi input_attribs[i].offset = 0;
2615*b7893ccfSSadaf Ebrahimi }
2616*b7893ccfSSadaf Ebrahimi // Let the last input_attribs description use same location as the first one
2617*b7893ccfSSadaf Ebrahimi input_attribs[attribute_count - 1].location = 0;
2618*b7893ccfSSadaf Ebrahimi // Let the last input_attribs description use binding which is not defined
2619*b7893ccfSSadaf Ebrahimi input_attribs[attribute_count - 1].binding = 1;
2620*b7893ccfSSadaf Ebrahimi
2621*b7893ccfSSadaf Ebrahimi const auto set_Info = [&](CreatePipelineHelper &helper) {
2622*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &input_binding;
2623*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
2624*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = input_attribs.data();
2625*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = attribute_count;
2626*b7893ccfSSadaf Ebrahimi };
2627*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
2628*b7893ccfSSadaf Ebrahimi *this, set_Info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2629*b7893ccfSSadaf Ebrahimi vector<string>{"VUID-VkPipelineVertexInputStateCreateInfo-vertexAttributeDescriptionCount-00614",
2630*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-binding-00615",
2631*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-pVertexAttributeDescriptions-00617"});
2632*b7893ccfSSadaf Ebrahimi }
2633*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,ColorBlendInvalidLogicOp)2634*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, ColorBlendInvalidLogicOp) {
2635*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Attempt to use invalid VkPipelineColorBlendStateCreateInfo::logicOp value.");
2636*b7893ccfSSadaf Ebrahimi
2637*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init()); // enables all supported features
2638*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2639*b7893ccfSSadaf Ebrahimi
2640*b7893ccfSSadaf Ebrahimi if (!m_device->phy().features().logicOp) {
2641*b7893ccfSSadaf Ebrahimi printf("%s Device does not support logicOp feature; skipped.\n", kSkipPrefix);
2642*b7893ccfSSadaf Ebrahimi return;
2643*b7893ccfSSadaf Ebrahimi }
2644*b7893ccfSSadaf Ebrahimi
2645*b7893ccfSSadaf Ebrahimi const auto set_shading_enable = [](CreatePipelineHelper &helper) {
2646*b7893ccfSSadaf Ebrahimi helper.cb_ci_.logicOpEnable = VK_TRUE;
2647*b7893ccfSSadaf Ebrahimi helper.cb_ci_.logicOp = static_cast<VkLogicOp>(VK_LOGIC_OP_END_RANGE + 1); // invalid logicOp to be tested
2648*b7893ccfSSadaf Ebrahimi };
2649*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2650*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00607");
2651*b7893ccfSSadaf Ebrahimi }
2652*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,ColorBlendUnsupportedLogicOp)2653*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, ColorBlendUnsupportedLogicOp) {
2654*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Attempt enabling VkPipelineColorBlendStateCreateInfo::logicOpEnable when logicOp feature is disabled.");
2655*b7893ccfSSadaf Ebrahimi
2656*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures features{};
2657*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init(&features));
2658*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2659*b7893ccfSSadaf Ebrahimi
2660*b7893ccfSSadaf Ebrahimi const auto set_shading_enable = [](CreatePipelineHelper &helper) { helper.cb_ci_.logicOpEnable = VK_TRUE; };
2661*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2662*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00606");
2663*b7893ccfSSadaf Ebrahimi }
2664*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,ColorBlendUnsupportedDualSourceBlend)2665*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, ColorBlendUnsupportedDualSourceBlend) {
2666*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Attempt to use dual-source blending when dualSrcBlend feature is disabled.");
2667*b7893ccfSSadaf Ebrahimi
2668*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures features{};
2669*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init(&features));
2670*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2671*b7893ccfSSadaf Ebrahimi
2672*b7893ccfSSadaf Ebrahimi VkPipelineColorBlendAttachmentState cb_attachments = {};
2673*b7893ccfSSadaf Ebrahimi
2674*b7893ccfSSadaf Ebrahimi const auto set_dsb_src_color_enable = [&](CreatePipelineHelper &helper) { helper.cb_attachments_ = cb_attachments; };
2675*b7893ccfSSadaf Ebrahimi
2676*b7893ccfSSadaf Ebrahimi cb_attachments.blendEnable = VK_TRUE;
2677*b7893ccfSSadaf Ebrahimi cb_attachments.srcColorBlendFactor = VK_BLEND_FACTOR_SRC1_COLOR; // bad!
2678*b7893ccfSSadaf Ebrahimi cb_attachments.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
2679*b7893ccfSSadaf Ebrahimi cb_attachments.colorBlendOp = VK_BLEND_OP_ADD;
2680*b7893ccfSSadaf Ebrahimi cb_attachments.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
2681*b7893ccfSSadaf Ebrahimi cb_attachments.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
2682*b7893ccfSSadaf Ebrahimi cb_attachments.alphaBlendOp = VK_BLEND_OP_ADD;
2683*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_dsb_src_color_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2684*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-srcColorBlendFactor-00608");
2685*b7893ccfSSadaf Ebrahimi
2686*b7893ccfSSadaf Ebrahimi cb_attachments.blendEnable = VK_TRUE;
2687*b7893ccfSSadaf Ebrahimi cb_attachments.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
2688*b7893ccfSSadaf Ebrahimi cb_attachments.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR; // bad
2689*b7893ccfSSadaf Ebrahimi cb_attachments.colorBlendOp = VK_BLEND_OP_ADD;
2690*b7893ccfSSadaf Ebrahimi cb_attachments.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
2691*b7893ccfSSadaf Ebrahimi cb_attachments.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
2692*b7893ccfSSadaf Ebrahimi cb_attachments.alphaBlendOp = VK_BLEND_OP_ADD;
2693*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_dsb_src_color_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2694*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-dstColorBlendFactor-00609");
2695*b7893ccfSSadaf Ebrahimi
2696*b7893ccfSSadaf Ebrahimi cb_attachments.blendEnable = VK_TRUE;
2697*b7893ccfSSadaf Ebrahimi cb_attachments.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
2698*b7893ccfSSadaf Ebrahimi cb_attachments.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
2699*b7893ccfSSadaf Ebrahimi cb_attachments.colorBlendOp = VK_BLEND_OP_ADD;
2700*b7893ccfSSadaf Ebrahimi cb_attachments.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC1_ALPHA; // bad
2701*b7893ccfSSadaf Ebrahimi cb_attachments.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
2702*b7893ccfSSadaf Ebrahimi cb_attachments.alphaBlendOp = VK_BLEND_OP_ADD;
2703*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_dsb_src_color_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2704*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-srcAlphaBlendFactor-00610");
2705*b7893ccfSSadaf Ebrahimi
2706*b7893ccfSSadaf Ebrahimi cb_attachments.blendEnable = VK_TRUE;
2707*b7893ccfSSadaf Ebrahimi cb_attachments.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
2708*b7893ccfSSadaf Ebrahimi cb_attachments.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
2709*b7893ccfSSadaf Ebrahimi cb_attachments.colorBlendOp = VK_BLEND_OP_ADD;
2710*b7893ccfSSadaf Ebrahimi cb_attachments.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
2711*b7893ccfSSadaf Ebrahimi cb_attachments.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA; // bad!
2712*b7893ccfSSadaf Ebrahimi cb_attachments.alphaBlendOp = VK_BLEND_OP_ADD;
2713*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_dsb_src_color_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2714*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-dstAlphaBlendFactor-00611");
2715*b7893ccfSSadaf Ebrahimi }
2716*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidSPIRVCodeSize)2717*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidSPIRVCodeSize) {
2718*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that errors are produced for a spirv modules with invalid code sizes");
2719*b7893ccfSSadaf Ebrahimi
2720*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header");
2721*b7893ccfSSadaf Ebrahimi
2722*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2723*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2724*b7893ccfSSadaf Ebrahimi
2725*b7893ccfSSadaf Ebrahimi VkShaderModule module;
2726*b7893ccfSSadaf Ebrahimi VkShaderModuleCreateInfo moduleCreateInfo;
2727*b7893ccfSSadaf Ebrahimi struct icd_spv_header spv;
2728*b7893ccfSSadaf Ebrahimi
2729*b7893ccfSSadaf Ebrahimi spv.magic = ICD_SPV_MAGIC;
2730*b7893ccfSSadaf Ebrahimi spv.version = ICD_SPV_VERSION;
2731*b7893ccfSSadaf Ebrahimi spv.gen_magic = 0;
2732*b7893ccfSSadaf Ebrahimi
2733*b7893ccfSSadaf Ebrahimi moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
2734*b7893ccfSSadaf Ebrahimi moduleCreateInfo.pNext = NULL;
2735*b7893ccfSSadaf Ebrahimi moduleCreateInfo.pCode = (const uint32_t *)&spv;
2736*b7893ccfSSadaf Ebrahimi moduleCreateInfo.codeSize = 4;
2737*b7893ccfSSadaf Ebrahimi moduleCreateInfo.flags = 0;
2738*b7893ccfSSadaf Ebrahimi vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
2739*b7893ccfSSadaf Ebrahimi
2740*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2741*b7893ccfSSadaf Ebrahimi
2742*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkShaderModuleCreateInfo-pCode-01376");
2743*b7893ccfSSadaf Ebrahimi std::vector<unsigned int> shader;
2744*b7893ccfSSadaf Ebrahimi VkShaderModuleCreateInfo module_create_info;
2745*b7893ccfSSadaf Ebrahimi VkShaderModule shader_module;
2746*b7893ccfSSadaf Ebrahimi module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
2747*b7893ccfSSadaf Ebrahimi module_create_info.pNext = NULL;
2748*b7893ccfSSadaf Ebrahimi this->GLSLtoSPV(VK_SHADER_STAGE_VERTEX_BIT, bindStateVertShaderText, shader);
2749*b7893ccfSSadaf Ebrahimi module_create_info.pCode = shader.data();
2750*b7893ccfSSadaf Ebrahimi // Introduce failure by making codeSize a non-multiple of 4
2751*b7893ccfSSadaf Ebrahimi module_create_info.codeSize = shader.size() * sizeof(unsigned int) - 1;
2752*b7893ccfSSadaf Ebrahimi module_create_info.flags = 0;
2753*b7893ccfSSadaf Ebrahimi vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
2754*b7893ccfSSadaf Ebrahimi
2755*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2756*b7893ccfSSadaf Ebrahimi }
2757*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,InvalidSPIRVMagic)2758*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, InvalidSPIRVMagic) {
2759*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that an error is produced for a spirv module with a bad magic number");
2760*b7893ccfSSadaf Ebrahimi
2761*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number");
2762*b7893ccfSSadaf Ebrahimi
2763*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2764*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2765*b7893ccfSSadaf Ebrahimi
2766*b7893ccfSSadaf Ebrahimi VkShaderModule module;
2767*b7893ccfSSadaf Ebrahimi VkShaderModuleCreateInfo moduleCreateInfo;
2768*b7893ccfSSadaf Ebrahimi struct icd_spv_header spv;
2769*b7893ccfSSadaf Ebrahimi
2770*b7893ccfSSadaf Ebrahimi spv.magic = (uint32_t)~ICD_SPV_MAGIC;
2771*b7893ccfSSadaf Ebrahimi spv.version = ICD_SPV_VERSION;
2772*b7893ccfSSadaf Ebrahimi spv.gen_magic = 0;
2773*b7893ccfSSadaf Ebrahimi
2774*b7893ccfSSadaf Ebrahimi moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
2775*b7893ccfSSadaf Ebrahimi moduleCreateInfo.pNext = NULL;
2776*b7893ccfSSadaf Ebrahimi moduleCreateInfo.pCode = (const uint32_t *)&spv;
2777*b7893ccfSSadaf Ebrahimi moduleCreateInfo.codeSize = sizeof(spv) + 16;
2778*b7893ccfSSadaf Ebrahimi moduleCreateInfo.flags = 0;
2779*b7893ccfSSadaf Ebrahimi vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
2780*b7893ccfSSadaf Ebrahimi
2781*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2782*b7893ccfSSadaf Ebrahimi }
2783*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineVertexOutputNotConsumed)2784*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) {
2785*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that a warning is produced for a vertex output that is not consumed by the fragment stage");
2786*b7893ccfSSadaf Ebrahimi
2787*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2788*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2789*b7893ccfSSadaf Ebrahimi
2790*b7893ccfSSadaf Ebrahimi char const *vsSource =
2791*b7893ccfSSadaf Ebrahimi "#version 450\n"
2792*b7893ccfSSadaf Ebrahimi "layout(location=0) out float x;\n"
2793*b7893ccfSSadaf Ebrahimi "void main(){\n"
2794*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(1);\n"
2795*b7893ccfSSadaf Ebrahimi " x = 0;\n"
2796*b7893ccfSSadaf Ebrahimi "}\n";
2797*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
2798*b7893ccfSSadaf Ebrahimi
2799*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
2800*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
2801*b7893ccfSSadaf Ebrahimi };
2802*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
2803*b7893ccfSSadaf Ebrahimi "not consumed by fragment shader");
2804*b7893ccfSSadaf Ebrahimi }
2805*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckShaderBadSpecialization)2806*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckShaderBadSpecialization) {
2807*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines.");
2808*b7893ccfSSadaf Ebrahimi
2809*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2810*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2811*b7893ccfSSadaf Ebrahimi
2812*b7893ccfSSadaf Ebrahimi char const *fsSource =
2813*b7893ccfSSadaf Ebrahimi "#version 450\n"
2814*b7893ccfSSadaf Ebrahimi "layout (constant_id = 0) const float r = 0.0f;\n"
2815*b7893ccfSSadaf Ebrahimi "layout(location = 0) out vec4 uFragColor;\n"
2816*b7893ccfSSadaf Ebrahimi "void main(){\n"
2817*b7893ccfSSadaf Ebrahimi " uFragColor = vec4(r,1,0,1);\n"
2818*b7893ccfSSadaf Ebrahimi "}\n";
2819*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2820*b7893ccfSSadaf Ebrahimi
2821*b7893ccfSSadaf Ebrahimi // This structure maps constant ids to data locations.
2822*b7893ccfSSadaf Ebrahimi const VkSpecializationMapEntry entry =
2823*b7893ccfSSadaf Ebrahimi // id, offset, size
2824*b7893ccfSSadaf Ebrahimi {0, 4, sizeof(uint32_t)}; // Challenge core validation by using a bogus offset.
2825*b7893ccfSSadaf Ebrahimi
2826*b7893ccfSSadaf Ebrahimi uint32_t data = 1;
2827*b7893ccfSSadaf Ebrahimi
2828*b7893ccfSSadaf Ebrahimi // Set up the info describing spec map and data
2829*b7893ccfSSadaf Ebrahimi const VkSpecializationInfo specialization_info = {
2830*b7893ccfSSadaf Ebrahimi 1,
2831*b7893ccfSSadaf Ebrahimi &entry,
2832*b7893ccfSSadaf Ebrahimi 1 * sizeof(float),
2833*b7893ccfSSadaf Ebrahimi &data,
2834*b7893ccfSSadaf Ebrahimi };
2835*b7893ccfSSadaf Ebrahimi
2836*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
2837*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
2838*b7893ccfSSadaf Ebrahimi helper.shader_stages_[1].pSpecializationInfo = &specialization_info;
2839*b7893ccfSSadaf Ebrahimi };
2840*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
2841*b7893ccfSSadaf Ebrahimi *this, set_info, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
2842*b7893ccfSSadaf Ebrahimi "Specialization entry 0 (for constant id 0) references memory outside provided specialization data ");
2843*b7893ccfSSadaf Ebrahimi }
2844*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckShaderDescriptorTypeMismatch)2845*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorTypeMismatch) {
2846*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines.");
2847*b7893ccfSSadaf Ebrahimi
2848*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2849*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2850*b7893ccfSSadaf Ebrahimi
2851*b7893ccfSSadaf Ebrahimi OneOffDescriptorSet descriptor_set(m_device, {
2852*b7893ccfSSadaf Ebrahimi {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
2853*b7893ccfSSadaf Ebrahimi });
2854*b7893ccfSSadaf Ebrahimi
2855*b7893ccfSSadaf Ebrahimi char const *vsSource =
2856*b7893ccfSSadaf Ebrahimi "#version 450\n"
2857*b7893ccfSSadaf Ebrahimi "\n"
2858*b7893ccfSSadaf Ebrahimi "layout (std140, set = 0, binding = 0) uniform buf {\n"
2859*b7893ccfSSadaf Ebrahimi " mat4 mvp;\n"
2860*b7893ccfSSadaf Ebrahimi "} ubuf;\n"
2861*b7893ccfSSadaf Ebrahimi "void main(){\n"
2862*b7893ccfSSadaf Ebrahimi " gl_Position = ubuf.mvp * vec4(1);\n"
2863*b7893ccfSSadaf Ebrahimi "}\n";
2864*b7893ccfSSadaf Ebrahimi
2865*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
2866*b7893ccfSSadaf Ebrahimi
2867*b7893ccfSSadaf Ebrahimi CreatePipelineHelper pipe(*this);
2868*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
2869*b7893ccfSSadaf Ebrahimi pipe.shader_stages_ = {vs.GetStageCreateInfo(), pipe.fs_->GetStageCreateInfo()};
2870*b7893ccfSSadaf Ebrahimi pipe.InitState();
2871*b7893ccfSSadaf Ebrahimi pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
2872*b7893ccfSSadaf Ebrahimi
2873*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on descriptor slot 0.0 ");
2874*b7893ccfSSadaf Ebrahimi pipe.CreateGraphicsPipeline();
2875*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2876*b7893ccfSSadaf Ebrahimi }
2877*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckShaderDescriptorNotAccessible)2878*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorNotAccessible) {
2879*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2880*b7893ccfSSadaf Ebrahimi "Create a pipeline in which a descriptor used by a shader stage does not include that stage in its stageFlags.");
2881*b7893ccfSSadaf Ebrahimi
2882*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2883*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2884*b7893ccfSSadaf Ebrahimi
2885*b7893ccfSSadaf Ebrahimi OneOffDescriptorSet ds(m_device, {
2886*b7893ccfSSadaf Ebrahimi {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT /*!*/, nullptr},
2887*b7893ccfSSadaf Ebrahimi });
2888*b7893ccfSSadaf Ebrahimi
2889*b7893ccfSSadaf Ebrahimi char const *vsSource =
2890*b7893ccfSSadaf Ebrahimi "#version 450\n"
2891*b7893ccfSSadaf Ebrahimi "\n"
2892*b7893ccfSSadaf Ebrahimi "layout (std140, set = 0, binding = 0) uniform buf {\n"
2893*b7893ccfSSadaf Ebrahimi " mat4 mvp;\n"
2894*b7893ccfSSadaf Ebrahimi "} ubuf;\n"
2895*b7893ccfSSadaf Ebrahimi "void main(){\n"
2896*b7893ccfSSadaf Ebrahimi " gl_Position = ubuf.mvp * vec4(1);\n"
2897*b7893ccfSSadaf Ebrahimi "}\n";
2898*b7893ccfSSadaf Ebrahimi
2899*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
2900*b7893ccfSSadaf Ebrahimi
2901*b7893ccfSSadaf Ebrahimi CreatePipelineHelper pipe(*this);
2902*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
2903*b7893ccfSSadaf Ebrahimi pipe.shader_stages_ = {vs.GetStageCreateInfo(), pipe.fs_->GetStageCreateInfo()};
2904*b7893ccfSSadaf Ebrahimi pipe.InitState();
2905*b7893ccfSSadaf Ebrahimi pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&ds.layout_});
2906*b7893ccfSSadaf Ebrahimi
2907*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0 ");
2908*b7893ccfSSadaf Ebrahimi pipe.CreateGraphicsPipeline();
2909*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2910*b7893ccfSSadaf Ebrahimi }
2911*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckShaderPushConstantNotAccessible)2912*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckShaderPushConstantNotAccessible) {
2913*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2914*b7893ccfSSadaf Ebrahimi "Create a graphics pipeline in which a push constant range containing a push constant block member is not accessible from "
2915*b7893ccfSSadaf Ebrahimi "the current shader stage.");
2916*b7893ccfSSadaf Ebrahimi
2917*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2918*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2919*b7893ccfSSadaf Ebrahimi
2920*b7893ccfSSadaf Ebrahimi char const *vsSource =
2921*b7893ccfSSadaf Ebrahimi "#version 450\n"
2922*b7893ccfSSadaf Ebrahimi "\n"
2923*b7893ccfSSadaf Ebrahimi "layout(push_constant, std430) uniform foo { float x; } consts;\n"
2924*b7893ccfSSadaf Ebrahimi "void main(){\n"
2925*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(consts.x);\n"
2926*b7893ccfSSadaf Ebrahimi "}\n";
2927*b7893ccfSSadaf Ebrahimi
2928*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
2929*b7893ccfSSadaf Ebrahimi
2930*b7893ccfSSadaf Ebrahimi // Set up a push constant range
2931*b7893ccfSSadaf Ebrahimi VkPushConstantRange push_constant_range = {};
2932*b7893ccfSSadaf Ebrahimi // Set to the wrong stage to challenge core_validation
2933*b7893ccfSSadaf Ebrahimi push_constant_range.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
2934*b7893ccfSSadaf Ebrahimi push_constant_range.size = 4;
2935*b7893ccfSSadaf Ebrahimi
2936*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pipeline_layout(m_device, {}, {push_constant_range});
2937*b7893ccfSSadaf Ebrahimi
2938*b7893ccfSSadaf Ebrahimi CreatePipelineHelper pipe(*this);
2939*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
2940*b7893ccfSSadaf Ebrahimi pipe.shader_stages_ = {vs.GetStageCreateInfo(), pipe.fs_->GetStageCreateInfo()};
2941*b7893ccfSSadaf Ebrahimi pipe.InitState();
2942*b7893ccfSSadaf Ebrahimi pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {}, {push_constant_range});
2943*b7893ccfSSadaf Ebrahimi
2944*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
2945*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
2946*b7893ccfSSadaf Ebrahimi "Push constant range covering variable starting at offset 0 not accessible from stage VK_SHADER_STAGE_VERTEX_BIT");
2947*b7893ccfSSadaf Ebrahimi pipe.CreateGraphicsPipeline();
2948*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2949*b7893ccfSSadaf Ebrahimi }
2950*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckShaderNotEnabled)2951*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckShaderNotEnabled) {
2952*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
2953*b7893ccfSSadaf Ebrahimi "Create a graphics pipeline in which a capability declared by the shader requires a feature not enabled on the device.");
2954*b7893ccfSSadaf Ebrahimi
2955*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2956*b7893ccfSSadaf Ebrahimi
2957*b7893ccfSSadaf Ebrahimi // Some awkward steps are required to test with custom device features.
2958*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures device_features = {};
2959*b7893ccfSSadaf Ebrahimi // Disable support for 64 bit floats
2960*b7893ccfSSadaf Ebrahimi device_features.shaderFloat64 = false;
2961*b7893ccfSSadaf Ebrahimi // The sacrificial device object
2962*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
2963*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2964*b7893ccfSSadaf Ebrahimi
2965*b7893ccfSSadaf Ebrahimi char const *fsSource =
2966*b7893ccfSSadaf Ebrahimi "#version 450\n"
2967*b7893ccfSSadaf Ebrahimi "\n"
2968*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
2969*b7893ccfSSadaf Ebrahimi "void main(){\n"
2970*b7893ccfSSadaf Ebrahimi " dvec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
2971*b7893ccfSSadaf Ebrahimi " color = vec4(green);\n"
2972*b7893ccfSSadaf Ebrahimi "}\n";
2973*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2974*b7893ccfSSadaf Ebrahimi
2975*b7893ccfSSadaf Ebrahimi CreatePipelineHelper pipe(*this);
2976*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
2977*b7893ccfSSadaf Ebrahimi pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
2978*b7893ccfSSadaf Ebrahimi pipe.InitState();
2979*b7893ccfSSadaf Ebrahimi pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device);
2980*b7893ccfSSadaf Ebrahimi
2981*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
2982*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader requires VkPhysicalDeviceFeatures::shaderFloat64 but is not enabled on the device");
2983*b7893ccfSSadaf Ebrahimi pipe.CreateGraphicsPipeline();
2984*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
2985*b7893ccfSSadaf Ebrahimi }
2986*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreateShaderModuleCheckBadCapability)2987*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreateShaderModuleCheckBadCapability) {
2988*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Create a shader in which a capability declared by the shader is not supported.");
2989*b7893ccfSSadaf Ebrahimi // Note that this failure message comes from spirv-tools, specifically the validator.
2990*b7893ccfSSadaf Ebrahimi
2991*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
2992*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2993*b7893ccfSSadaf Ebrahimi
2994*b7893ccfSSadaf Ebrahimi const std::string spv_source = R"(
2995*b7893ccfSSadaf Ebrahimi OpCapability ImageRect
2996*b7893ccfSSadaf Ebrahimi OpEntryPoint Vertex %main "main"
2997*b7893ccfSSadaf Ebrahimi %main = OpFunction %void None %3
2998*b7893ccfSSadaf Ebrahimi OpReturn
2999*b7893ccfSSadaf Ebrahimi OpFunctionEnd
3000*b7893ccfSSadaf Ebrahimi )";
3001*b7893ccfSSadaf Ebrahimi
3002*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Capability ImageRect is not allowed by Vulkan");
3003*b7893ccfSSadaf Ebrahimi
3004*b7893ccfSSadaf Ebrahimi std::vector<unsigned int> spv;
3005*b7893ccfSSadaf Ebrahimi VkShaderModuleCreateInfo module_create_info;
3006*b7893ccfSSadaf Ebrahimi VkShaderModule shader_module;
3007*b7893ccfSSadaf Ebrahimi module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
3008*b7893ccfSSadaf Ebrahimi module_create_info.pNext = NULL;
3009*b7893ccfSSadaf Ebrahimi ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, spv_source.data(), spv);
3010*b7893ccfSSadaf Ebrahimi module_create_info.pCode = spv.data();
3011*b7893ccfSSadaf Ebrahimi module_create_info.codeSize = spv.size() * sizeof(unsigned int);
3012*b7893ccfSSadaf Ebrahimi module_create_info.flags = 0;
3013*b7893ccfSSadaf Ebrahimi
3014*b7893ccfSSadaf Ebrahimi VkResult err = vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
3015*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
3016*b7893ccfSSadaf Ebrahimi if (err == VK_SUCCESS) {
3017*b7893ccfSSadaf Ebrahimi vkDestroyShaderModule(m_device->handle(), shader_module, NULL);
3018*b7893ccfSSadaf Ebrahimi }
3019*b7893ccfSSadaf Ebrahimi }
3020*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineFragmentInputNotProvided)3021*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
3022*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3023*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a fragment shader input which is not present in the outputs of the previous stage");
3024*b7893ccfSSadaf Ebrahimi
3025*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3026*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3027*b7893ccfSSadaf Ebrahimi
3028*b7893ccfSSadaf Ebrahimi char const *fsSource =
3029*b7893ccfSSadaf Ebrahimi "#version 450\n"
3030*b7893ccfSSadaf Ebrahimi "\n"
3031*b7893ccfSSadaf Ebrahimi "layout(location=0) in float x;\n"
3032*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3033*b7893ccfSSadaf Ebrahimi "void main(){\n"
3034*b7893ccfSSadaf Ebrahimi " color = vec4(x);\n"
3035*b7893ccfSSadaf Ebrahimi "}\n";
3036*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3037*b7893ccfSSadaf Ebrahimi
3038*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3039*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3040*b7893ccfSSadaf Ebrahimi };
3041*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
3042*b7893ccfSSadaf Ebrahimi }
3043*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineFragmentInputNotProvidedInBlock)3044*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) {
3045*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3046*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a fragment shader input within an interace block, which is not present in the outputs "
3047*b7893ccfSSadaf Ebrahimi "of the previous stage.");
3048*b7893ccfSSadaf Ebrahimi
3049*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3050*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3051*b7893ccfSSadaf Ebrahimi
3052*b7893ccfSSadaf Ebrahimi char const *fsSource =
3053*b7893ccfSSadaf Ebrahimi "#version 450\n"
3054*b7893ccfSSadaf Ebrahimi "\n"
3055*b7893ccfSSadaf Ebrahimi "in block { layout(location=0) float x; } ins;\n"
3056*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3057*b7893ccfSSadaf Ebrahimi "void main(){\n"
3058*b7893ccfSSadaf Ebrahimi " color = vec4(ins.x);\n"
3059*b7893ccfSSadaf Ebrahimi "}\n";
3060*b7893ccfSSadaf Ebrahimi
3061*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3062*b7893ccfSSadaf Ebrahimi
3063*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3064*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3065*b7893ccfSSadaf Ebrahimi };
3066*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
3067*b7893ccfSSadaf Ebrahimi }
3068*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineVsFsTypeMismatchArraySize)3069*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
3070*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes across the vertex->fragment shader interface");
3071*b7893ccfSSadaf Ebrahimi
3072*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3073*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3074*b7893ccfSSadaf Ebrahimi
3075*b7893ccfSSadaf Ebrahimi char const *vsSource =
3076*b7893ccfSSadaf Ebrahimi "#version 450\n"
3077*b7893ccfSSadaf Ebrahimi "\n"
3078*b7893ccfSSadaf Ebrahimi "layout(location=0) out float x[2];\n"
3079*b7893ccfSSadaf Ebrahimi "void main(){\n"
3080*b7893ccfSSadaf Ebrahimi " x[0] = 0; x[1] = 0;\n"
3081*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(1);\n"
3082*b7893ccfSSadaf Ebrahimi "}\n";
3083*b7893ccfSSadaf Ebrahimi char const *fsSource =
3084*b7893ccfSSadaf Ebrahimi "#version 450\n"
3085*b7893ccfSSadaf Ebrahimi "\n"
3086*b7893ccfSSadaf Ebrahimi "layout(location=0) in float x[1];\n"
3087*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3088*b7893ccfSSadaf Ebrahimi "void main(){\n"
3089*b7893ccfSSadaf Ebrahimi " color = vec4(x[0]);\n"
3090*b7893ccfSSadaf Ebrahimi "}\n";
3091*b7893ccfSSadaf Ebrahimi
3092*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3093*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3094*b7893ccfSSadaf Ebrahimi
3095*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3096*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3097*b7893ccfSSadaf Ebrahimi };
3098*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
3099*b7893ccfSSadaf Ebrahimi *this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3100*b7893ccfSSadaf Ebrahimi "Type mismatch on location 0.0: 'ptr to output arr[2] of float32' vs 'ptr to input arr[1] of float32'");
3101*b7893ccfSSadaf Ebrahimi }
3102*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineVsFsTypeMismatch)3103*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
3104*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that an error is produced for mismatched types across the vertex->fragment shader interface");
3105*b7893ccfSSadaf Ebrahimi
3106*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3107*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3108*b7893ccfSSadaf Ebrahimi
3109*b7893ccfSSadaf Ebrahimi char const *vsSource =
3110*b7893ccfSSadaf Ebrahimi "#version 450\n"
3111*b7893ccfSSadaf Ebrahimi "\n"
3112*b7893ccfSSadaf Ebrahimi "layout(location=0) out int x;\n"
3113*b7893ccfSSadaf Ebrahimi "void main(){\n"
3114*b7893ccfSSadaf Ebrahimi " x = 0;\n"
3115*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(1);\n"
3116*b7893ccfSSadaf Ebrahimi "}\n";
3117*b7893ccfSSadaf Ebrahimi char const *fsSource =
3118*b7893ccfSSadaf Ebrahimi "#version 450\n"
3119*b7893ccfSSadaf Ebrahimi "\n"
3120*b7893ccfSSadaf Ebrahimi "layout(location=0) in float x;\n" /* VS writes int */
3121*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3122*b7893ccfSSadaf Ebrahimi "void main(){\n"
3123*b7893ccfSSadaf Ebrahimi " color = vec4(x);\n"
3124*b7893ccfSSadaf Ebrahimi "}\n";
3125*b7893ccfSSadaf Ebrahimi
3126*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3127*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3128*b7893ccfSSadaf Ebrahimi
3129*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3130*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3131*b7893ccfSSadaf Ebrahimi };
3132*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
3133*b7893ccfSSadaf Ebrahimi }
3134*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineVsFsTypeMismatchInBlock)3135*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
3136*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3137*b7893ccfSSadaf Ebrahimi "Test that an error is produced for mismatched types across the vertex->fragment shader interface, when the variable is "
3138*b7893ccfSSadaf Ebrahimi "contained within an interface block");
3139*b7893ccfSSadaf Ebrahimi
3140*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3141*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3142*b7893ccfSSadaf Ebrahimi
3143*b7893ccfSSadaf Ebrahimi char const *vsSource =
3144*b7893ccfSSadaf Ebrahimi "#version 450\n"
3145*b7893ccfSSadaf Ebrahimi "\n"
3146*b7893ccfSSadaf Ebrahimi "out block { layout(location=0) int x; } outs;\n"
3147*b7893ccfSSadaf Ebrahimi "void main(){\n"
3148*b7893ccfSSadaf Ebrahimi " outs.x = 0;\n"
3149*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(1);\n"
3150*b7893ccfSSadaf Ebrahimi "}\n";
3151*b7893ccfSSadaf Ebrahimi char const *fsSource =
3152*b7893ccfSSadaf Ebrahimi "#version 450\n"
3153*b7893ccfSSadaf Ebrahimi "\n"
3154*b7893ccfSSadaf Ebrahimi "in block { layout(location=0) float x; } ins;\n" /* VS writes int */
3155*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3156*b7893ccfSSadaf Ebrahimi "void main(){\n"
3157*b7893ccfSSadaf Ebrahimi " color = vec4(ins.x);\n"
3158*b7893ccfSSadaf Ebrahimi "}\n";
3159*b7893ccfSSadaf Ebrahimi
3160*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3161*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3162*b7893ccfSSadaf Ebrahimi
3163*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3164*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3165*b7893ccfSSadaf Ebrahimi };
3166*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
3167*b7893ccfSSadaf Ebrahimi }
3168*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineVsFsMismatchByLocation)3169*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
3170*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3171*b7893ccfSSadaf Ebrahimi "Test that an error is produced for location mismatches across the vertex->fragment shader interface; This should manifest "
3172*b7893ccfSSadaf Ebrahimi "as a not-written/not-consumed pair, but flushes out broken walking of the interfaces");
3173*b7893ccfSSadaf Ebrahimi
3174*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3175*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3176*b7893ccfSSadaf Ebrahimi
3177*b7893ccfSSadaf Ebrahimi char const *vsSource =
3178*b7893ccfSSadaf Ebrahimi "#version 450\n"
3179*b7893ccfSSadaf Ebrahimi "\n"
3180*b7893ccfSSadaf Ebrahimi "out block { layout(location=1) float x; } outs;\n"
3181*b7893ccfSSadaf Ebrahimi "void main(){\n"
3182*b7893ccfSSadaf Ebrahimi " outs.x = 0;\n"
3183*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(1);\n"
3184*b7893ccfSSadaf Ebrahimi "}\n";
3185*b7893ccfSSadaf Ebrahimi char const *fsSource =
3186*b7893ccfSSadaf Ebrahimi "#version 450\n"
3187*b7893ccfSSadaf Ebrahimi "\n"
3188*b7893ccfSSadaf Ebrahimi "in block { layout(location=0) float x; } ins;\n"
3189*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3190*b7893ccfSSadaf Ebrahimi "void main(){\n"
3191*b7893ccfSSadaf Ebrahimi " color = vec4(ins.x);\n"
3192*b7893ccfSSadaf Ebrahimi "}\n";
3193*b7893ccfSSadaf Ebrahimi
3194*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3195*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3196*b7893ccfSSadaf Ebrahimi
3197*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3198*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3199*b7893ccfSSadaf Ebrahimi };
3200*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3201*b7893ccfSSadaf Ebrahimi "location 0.0 which is not written by vertex shader");
3202*b7893ccfSSadaf Ebrahimi }
3203*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineVsFsMismatchByComponent)3204*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
3205*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3206*b7893ccfSSadaf Ebrahimi "Test that an error is produced for component mismatches across the vertex->fragment shader interface. It's not enough to "
3207*b7893ccfSSadaf Ebrahimi "have the same set of locations in use; matching is defined in terms of spirv variables.");
3208*b7893ccfSSadaf Ebrahimi
3209*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3210*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3211*b7893ccfSSadaf Ebrahimi
3212*b7893ccfSSadaf Ebrahimi char const *vsSource =
3213*b7893ccfSSadaf Ebrahimi "#version 450\n"
3214*b7893ccfSSadaf Ebrahimi "\n"
3215*b7893ccfSSadaf Ebrahimi "out block { layout(location=0, component=0) float x; } outs;\n"
3216*b7893ccfSSadaf Ebrahimi "void main(){\n"
3217*b7893ccfSSadaf Ebrahimi " outs.x = 0;\n"
3218*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(1);\n"
3219*b7893ccfSSadaf Ebrahimi "}\n";
3220*b7893ccfSSadaf Ebrahimi char const *fsSource =
3221*b7893ccfSSadaf Ebrahimi "#version 450\n"
3222*b7893ccfSSadaf Ebrahimi "\n"
3223*b7893ccfSSadaf Ebrahimi "in block { layout(location=0, component=1) float x; } ins;\n"
3224*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3225*b7893ccfSSadaf Ebrahimi "void main(){\n"
3226*b7893ccfSSadaf Ebrahimi " color = vec4(ins.x);\n"
3227*b7893ccfSSadaf Ebrahimi "}\n";
3228*b7893ccfSSadaf Ebrahimi
3229*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3230*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3231*b7893ccfSSadaf Ebrahimi
3232*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3233*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3234*b7893ccfSSadaf Ebrahimi };
3235*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3236*b7893ccfSSadaf Ebrahimi "location 0.1 which is not written by vertex shader");
3237*b7893ccfSSadaf Ebrahimi }
3238*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineVsFsMismatchByPrecision)3239*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByPrecision) {
3240*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that the RelaxedPrecision decoration is validated to match");
3241*b7893ccfSSadaf Ebrahimi
3242*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3243*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3244*b7893ccfSSadaf Ebrahimi
3245*b7893ccfSSadaf Ebrahimi char const *vsSource =
3246*b7893ccfSSadaf Ebrahimi "#version 450\n"
3247*b7893ccfSSadaf Ebrahimi "layout(location=0) out mediump float x;\n"
3248*b7893ccfSSadaf Ebrahimi "void main() { gl_Position = vec4(0); x = 1.0; }\n";
3249*b7893ccfSSadaf Ebrahimi char const *fsSource =
3250*b7893ccfSSadaf Ebrahimi "#version 450\n"
3251*b7893ccfSSadaf Ebrahimi "layout(location=0) in highp float x;\n"
3252*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3253*b7893ccfSSadaf Ebrahimi "void main() { color = vec4(x); }\n";
3254*b7893ccfSSadaf Ebrahimi
3255*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3256*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3257*b7893ccfSSadaf Ebrahimi
3258*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3259*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3260*b7893ccfSSadaf Ebrahimi };
3261*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "differ in precision");
3262*b7893ccfSSadaf Ebrahimi }
3263*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineVsFsMismatchByPrecisionBlock)3264*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByPrecisionBlock) {
3265*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that the RelaxedPrecision decoration is validated to match");
3266*b7893ccfSSadaf Ebrahimi
3267*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3268*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3269*b7893ccfSSadaf Ebrahimi
3270*b7893ccfSSadaf Ebrahimi char const *vsSource =
3271*b7893ccfSSadaf Ebrahimi "#version 450\n"
3272*b7893ccfSSadaf Ebrahimi "out block { layout(location=0) mediump float x; };\n"
3273*b7893ccfSSadaf Ebrahimi "void main() { gl_Position = vec4(0); x = 1.0; }\n";
3274*b7893ccfSSadaf Ebrahimi char const *fsSource =
3275*b7893ccfSSadaf Ebrahimi "#version 450\n"
3276*b7893ccfSSadaf Ebrahimi "in block { layout(location=0) highp float x; };\n"
3277*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3278*b7893ccfSSadaf Ebrahimi "void main() { color = vec4(x); }\n";
3279*b7893ccfSSadaf Ebrahimi
3280*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3281*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3282*b7893ccfSSadaf Ebrahimi
3283*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3284*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3285*b7893ccfSSadaf Ebrahimi };
3286*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "differ in precision");
3287*b7893ccfSSadaf Ebrahimi }
3288*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineAttribNotConsumed)3289*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
3290*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is not consumed by the vertex shader");
3291*b7893ccfSSadaf Ebrahimi
3292*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3293*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3294*b7893ccfSSadaf Ebrahimi
3295*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription input_binding;
3296*b7893ccfSSadaf Ebrahimi memset(&input_binding, 0, sizeof(input_binding));
3297*b7893ccfSSadaf Ebrahimi
3298*b7893ccfSSadaf Ebrahimi VkVertexInputAttributeDescription input_attrib;
3299*b7893ccfSSadaf Ebrahimi memset(&input_attrib, 0, sizeof(input_attrib));
3300*b7893ccfSSadaf Ebrahimi input_attrib.format = VK_FORMAT_R32_SFLOAT;
3301*b7893ccfSSadaf Ebrahimi
3302*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3303*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &input_binding;
3304*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
3305*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = &input_attrib;
3306*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = 1;
3307*b7893ccfSSadaf Ebrahimi };
3308*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
3309*b7893ccfSSadaf Ebrahimi "location 0 not consumed by vertex shader");
3310*b7893ccfSSadaf Ebrahimi }
3311*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineAttribLocationMismatch)3312*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
3313*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3314*b7893ccfSSadaf Ebrahimi "Test that a warning is produced for a location mismatch on vertex attributes. This flushes out bad behavior in the "
3315*b7893ccfSSadaf Ebrahimi "interface walker");
3316*b7893ccfSSadaf Ebrahimi
3317*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3318*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3319*b7893ccfSSadaf Ebrahimi
3320*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription input_binding;
3321*b7893ccfSSadaf Ebrahimi memset(&input_binding, 0, sizeof(input_binding));
3322*b7893ccfSSadaf Ebrahimi
3323*b7893ccfSSadaf Ebrahimi VkVertexInputAttributeDescription input_attrib;
3324*b7893ccfSSadaf Ebrahimi memset(&input_attrib, 0, sizeof(input_attrib));
3325*b7893ccfSSadaf Ebrahimi input_attrib.format = VK_FORMAT_R32_SFLOAT;
3326*b7893ccfSSadaf Ebrahimi
3327*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3328*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &input_binding;
3329*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
3330*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = &input_attrib;
3331*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = 1;
3332*b7893ccfSSadaf Ebrahimi };
3333*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetUnexpectedError("Vertex shader consumes input at location 1 but not provided");
3334*b7893ccfSSadaf Ebrahimi
3335*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
3336*b7893ccfSSadaf Ebrahimi "location 0 not consumed by vertex shader");
3337*b7893ccfSSadaf Ebrahimi }
3338*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineAttribNotProvided)3339*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
3340*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not provided by a vertex attribute");
3341*b7893ccfSSadaf Ebrahimi
3342*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3343*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3344*b7893ccfSSadaf Ebrahimi
3345*b7893ccfSSadaf Ebrahimi char const *vsSource =
3346*b7893ccfSSadaf Ebrahimi "#version 450\n"
3347*b7893ccfSSadaf Ebrahimi "\n"
3348*b7893ccfSSadaf Ebrahimi "layout(location=0) in vec4 x;\n" /* not provided */
3349*b7893ccfSSadaf Ebrahimi "void main(){\n"
3350*b7893ccfSSadaf Ebrahimi " gl_Position = x;\n"
3351*b7893ccfSSadaf Ebrahimi "}\n";
3352*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3353*b7893ccfSSadaf Ebrahimi
3354*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3355*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
3356*b7893ccfSSadaf Ebrahimi };
3357*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3358*b7893ccfSSadaf Ebrahimi "Vertex shader consumes input at location 0 but not provided");
3359*b7893ccfSSadaf Ebrahimi }
3360*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineAttribTypeMismatch)3361*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
3362*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3363*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a mismatch between the fundamental type (float/int/uint) of an attribute and the "
3364*b7893ccfSSadaf Ebrahimi "vertex shader input that consumes it");
3365*b7893ccfSSadaf Ebrahimi
3366*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3367*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3368*b7893ccfSSadaf Ebrahimi
3369*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription input_binding;
3370*b7893ccfSSadaf Ebrahimi memset(&input_binding, 0, sizeof(input_binding));
3371*b7893ccfSSadaf Ebrahimi
3372*b7893ccfSSadaf Ebrahimi VkVertexInputAttributeDescription input_attrib;
3373*b7893ccfSSadaf Ebrahimi memset(&input_attrib, 0, sizeof(input_attrib));
3374*b7893ccfSSadaf Ebrahimi input_attrib.format = VK_FORMAT_R32_SFLOAT;
3375*b7893ccfSSadaf Ebrahimi
3376*b7893ccfSSadaf Ebrahimi char const *vsSource =
3377*b7893ccfSSadaf Ebrahimi "#version 450\n"
3378*b7893ccfSSadaf Ebrahimi "\n"
3379*b7893ccfSSadaf Ebrahimi "layout(location=0) in int x;\n" /* attrib provided float */
3380*b7893ccfSSadaf Ebrahimi "void main(){\n"
3381*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(x);\n"
3382*b7893ccfSSadaf Ebrahimi "}\n";
3383*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3384*b7893ccfSSadaf Ebrahimi
3385*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3386*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
3387*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = &input_binding;
3388*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 1;
3389*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = &input_attrib;
3390*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = 1;
3391*b7893ccfSSadaf Ebrahimi };
3392*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3393*b7893ccfSSadaf Ebrahimi "location 0 does not match vertex shader input type");
3394*b7893ccfSSadaf Ebrahimi }
3395*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineDuplicateStage)3396*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineDuplicateStage) {
3397*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple shaders for the same stage");
3398*b7893ccfSSadaf Ebrahimi
3399*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3400*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3401*b7893ccfSSadaf Ebrahimi
3402*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3403*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), helper.vs_->GetStageCreateInfo(),
3404*b7893ccfSSadaf Ebrahimi helper.fs_->GetStageCreateInfo()};
3405*b7893ccfSSadaf Ebrahimi };
3406*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3407*b7893ccfSSadaf Ebrahimi "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT");
3408*b7893ccfSSadaf Ebrahimi }
3409*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineMissingEntrypoint)3410*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) {
3411*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3412*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3413*b7893ccfSSadaf Ebrahimi
3414*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo");
3415*b7893ccfSSadaf Ebrahimi
3416*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3417*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3418*b7893ccfSSadaf Ebrahimi };
3419*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "No entrypoint found named `foo`");
3420*b7893ccfSSadaf Ebrahimi }
3421*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineDepthStencilRequired)3422*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) {
3423*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
3424*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
3425*b7893ccfSSadaf Ebrahimi "pDepthStencilState is NULL when rasterization is enabled and subpass uses a depth/stencil attachment");
3426*b7893ccfSSadaf Ebrahimi
3427*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3428*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3429*b7893ccfSSadaf Ebrahimi
3430*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
3431*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3432*b7893ccfSSadaf Ebrahimi
3433*b7893ccfSSadaf Ebrahimi VkPipelineObj pipe(m_device);
3434*b7893ccfSSadaf Ebrahimi pipe.AddDefaultColorAttachment();
3435*b7893ccfSSadaf Ebrahimi pipe.AddShader(&vs);
3436*b7893ccfSSadaf Ebrahimi pipe.AddShader(&fs);
3437*b7893ccfSSadaf Ebrahimi
3438*b7893ccfSSadaf Ebrahimi VkDescriptorSetObj descriptorSet(m_device);
3439*b7893ccfSSadaf Ebrahimi descriptorSet.AppendDummy();
3440*b7893ccfSSadaf Ebrahimi descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
3441*b7893ccfSSadaf Ebrahimi
3442*b7893ccfSSadaf Ebrahimi VkAttachmentDescription attachments[] = {
3443*b7893ccfSSadaf Ebrahimi {
3444*b7893ccfSSadaf Ebrahimi 0,
3445*b7893ccfSSadaf Ebrahimi VK_FORMAT_B8G8R8A8_UNORM,
3446*b7893ccfSSadaf Ebrahimi VK_SAMPLE_COUNT_1_BIT,
3447*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3448*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_STORE_OP_DONT_CARE,
3449*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3450*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_STORE_OP_DONT_CARE,
3451*b7893ccfSSadaf Ebrahimi VK_IMAGE_LAYOUT_UNDEFINED,
3452*b7893ccfSSadaf Ebrahimi VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3453*b7893ccfSSadaf Ebrahimi },
3454*b7893ccfSSadaf Ebrahimi {
3455*b7893ccfSSadaf Ebrahimi 0,
3456*b7893ccfSSadaf Ebrahimi VK_FORMAT_D16_UNORM,
3457*b7893ccfSSadaf Ebrahimi VK_SAMPLE_COUNT_1_BIT,
3458*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3459*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_STORE_OP_DONT_CARE,
3460*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3461*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_STORE_OP_DONT_CARE,
3462*b7893ccfSSadaf Ebrahimi VK_IMAGE_LAYOUT_UNDEFINED,
3463*b7893ccfSSadaf Ebrahimi VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3464*b7893ccfSSadaf Ebrahimi },
3465*b7893ccfSSadaf Ebrahimi };
3466*b7893ccfSSadaf Ebrahimi VkAttachmentReference refs[] = {
3467*b7893ccfSSadaf Ebrahimi {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
3468*b7893ccfSSadaf Ebrahimi {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
3469*b7893ccfSSadaf Ebrahimi };
3470*b7893ccfSSadaf Ebrahimi VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &refs[0], nullptr, &refs[1], 0, nullptr};
3471*b7893ccfSSadaf Ebrahimi VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
3472*b7893ccfSSadaf Ebrahimi VkRenderPass rp;
3473*b7893ccfSSadaf Ebrahimi VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3474*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
3475*b7893ccfSSadaf Ebrahimi
3476*b7893ccfSSadaf Ebrahimi pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp);
3477*b7893ccfSSadaf Ebrahimi
3478*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
3479*b7893ccfSSadaf Ebrahimi
3480*b7893ccfSSadaf Ebrahimi vkDestroyRenderPass(m_device->device(), rp, nullptr);
3481*b7893ccfSSadaf Ebrahimi }
3482*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineTessPatchDecorationMismatch)3483*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) {
3484*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3485*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a variable output from the TCS without the patch decoration, but consumed in the TES "
3486*b7893ccfSSadaf Ebrahimi "with the decoration.");
3487*b7893ccfSSadaf Ebrahimi
3488*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3489*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3490*b7893ccfSSadaf Ebrahimi
3491*b7893ccfSSadaf Ebrahimi if (!m_device->phy().features().tessellationShader) {
3492*b7893ccfSSadaf Ebrahimi printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
3493*b7893ccfSSadaf Ebrahimi return;
3494*b7893ccfSSadaf Ebrahimi }
3495*b7893ccfSSadaf Ebrahimi
3496*b7893ccfSSadaf Ebrahimi char const *tcsSource =
3497*b7893ccfSSadaf Ebrahimi "#version 450\n"
3498*b7893ccfSSadaf Ebrahimi "layout(location=0) out int x[];\n"
3499*b7893ccfSSadaf Ebrahimi "layout(vertices=3) out;\n"
3500*b7893ccfSSadaf Ebrahimi "void main(){\n"
3501*b7893ccfSSadaf Ebrahimi " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
3502*b7893ccfSSadaf Ebrahimi " gl_TessLevelInner[0] = 1;\n"
3503*b7893ccfSSadaf Ebrahimi " x[gl_InvocationID] = gl_InvocationID;\n"
3504*b7893ccfSSadaf Ebrahimi "}\n";
3505*b7893ccfSSadaf Ebrahimi char const *tesSource =
3506*b7893ccfSSadaf Ebrahimi "#version 450\n"
3507*b7893ccfSSadaf Ebrahimi "layout(triangles, equal_spacing, cw) in;\n"
3508*b7893ccfSSadaf Ebrahimi "layout(location=0) patch in int x;\n"
3509*b7893ccfSSadaf Ebrahimi "void main(){\n"
3510*b7893ccfSSadaf Ebrahimi " gl_Position.xyz = gl_TessCoord;\n"
3511*b7893ccfSSadaf Ebrahimi " gl_Position.w = x;\n"
3512*b7893ccfSSadaf Ebrahimi "}\n";
3513*b7893ccfSSadaf Ebrahimi VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
3514*b7893ccfSSadaf Ebrahimi VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
3515*b7893ccfSSadaf Ebrahimi
3516*b7893ccfSSadaf Ebrahimi VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
3517*b7893ccfSSadaf Ebrahimi VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
3518*b7893ccfSSadaf Ebrahimi
3519*b7893ccfSSadaf Ebrahimi VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
3520*b7893ccfSSadaf Ebrahimi
3521*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3522*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pTessellationState = &tsci;
3523*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pInputAssemblyState = &iasci;
3524*b7893ccfSSadaf Ebrahimi helper.shader_stages_.emplace_back(tcs.GetStageCreateInfo());
3525*b7893ccfSSadaf Ebrahimi helper.shader_stages_.emplace_back(tes.GetStageCreateInfo());
3526*b7893ccfSSadaf Ebrahimi };
3527*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
3528*b7893ccfSSadaf Ebrahimi *this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3529*b7893ccfSSadaf Ebrahimi "is per-vertex in tessellation control shader stage but per-patch in tessellation evaluation shader stage");
3530*b7893ccfSSadaf Ebrahimi }
3531*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineTessErrors)3532*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineTessErrors) {
3533*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test various errors when creating a graphics pipeline with tessellation stages active.");
3534*b7893ccfSSadaf Ebrahimi
3535*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3536*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3537*b7893ccfSSadaf Ebrahimi
3538*b7893ccfSSadaf Ebrahimi if (!m_device->phy().features().tessellationShader) {
3539*b7893ccfSSadaf Ebrahimi printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
3540*b7893ccfSSadaf Ebrahimi return;
3541*b7893ccfSSadaf Ebrahimi }
3542*b7893ccfSSadaf Ebrahimi
3543*b7893ccfSSadaf Ebrahimi char const *tcsSource =
3544*b7893ccfSSadaf Ebrahimi "#version 450\n"
3545*b7893ccfSSadaf Ebrahimi "layout(vertices=3) out;\n"
3546*b7893ccfSSadaf Ebrahimi "void main(){\n"
3547*b7893ccfSSadaf Ebrahimi " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
3548*b7893ccfSSadaf Ebrahimi " gl_TessLevelInner[0] = 1;\n"
3549*b7893ccfSSadaf Ebrahimi "}\n";
3550*b7893ccfSSadaf Ebrahimi char const *tesSource =
3551*b7893ccfSSadaf Ebrahimi "#version 450\n"
3552*b7893ccfSSadaf Ebrahimi "layout(triangles, equal_spacing, cw) in;\n"
3553*b7893ccfSSadaf Ebrahimi "void main(){\n"
3554*b7893ccfSSadaf Ebrahimi " gl_Position.xyz = gl_TessCoord;\n"
3555*b7893ccfSSadaf Ebrahimi " gl_Position.w = 0;\n"
3556*b7893ccfSSadaf Ebrahimi "}\n";
3557*b7893ccfSSadaf Ebrahimi VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
3558*b7893ccfSSadaf Ebrahimi VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
3559*b7893ccfSSadaf Ebrahimi
3560*b7893ccfSSadaf Ebrahimi VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
3561*b7893ccfSSadaf Ebrahimi VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
3562*b7893ccfSSadaf Ebrahimi
3563*b7893ccfSSadaf Ebrahimi VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
3564*b7893ccfSSadaf Ebrahimi
3565*b7893ccfSSadaf Ebrahimi std::vector<VkPipelineShaderStageCreateInfo> shader_stages = {};
3566*b7893ccfSSadaf Ebrahimi VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
3567*b7893ccfSSadaf Ebrahimi VkPipelineInputAssemblyStateCreateInfo *p_iasci = nullptr;
3568*b7893ccfSSadaf Ebrahimi VkPipelineTessellationStateCreateInfo tsci_bad = tsci;
3569*b7893ccfSSadaf Ebrahimi VkPipelineTessellationStateCreateInfo *p_tsci = nullptr;
3570*b7893ccfSSadaf Ebrahimi
3571*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3572*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pTessellationState = p_tsci;
3573*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pInputAssemblyState = p_iasci;
3574*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
3575*b7893ccfSSadaf Ebrahimi helper.shader_stages_.insert(helper.shader_stages_.end(), shader_stages.begin(), shader_stages.end());
3576*b7893ccfSSadaf Ebrahimi };
3577*b7893ccfSSadaf Ebrahimi
3578*b7893ccfSSadaf Ebrahimi iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; // otherwise we get a failure about invalid topology
3579*b7893ccfSSadaf Ebrahimi p_iasci = &iasci_bad;
3580*b7893ccfSSadaf Ebrahimi // Pass a tess control shader without a tess eval shader
3581*b7893ccfSSadaf Ebrahimi shader_stages = {tcs.GetStageCreateInfo()};
3582*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3583*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pStages-00729");
3584*b7893ccfSSadaf Ebrahimi
3585*b7893ccfSSadaf Ebrahimi // Pass a tess eval shader without a tess control shader
3586*b7893ccfSSadaf Ebrahimi shader_stages = {tes.GetStageCreateInfo()};
3587*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3588*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pStages-00730");
3589*b7893ccfSSadaf Ebrahimi
3590*b7893ccfSSadaf Ebrahimi p_iasci = &iasci;
3591*b7893ccfSSadaf Ebrahimi shader_stages = {};
3592*b7893ccfSSadaf Ebrahimi // Pass patch topology without tessellation shaders
3593*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3594*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-topology-00737");
3595*b7893ccfSSadaf Ebrahimi
3596*b7893ccfSSadaf Ebrahimi shader_stages = {tcs.GetStageCreateInfo(), tes.GetStageCreateInfo()};
3597*b7893ccfSSadaf Ebrahimi // Pass a NULL pTessellationState (with active tessellation shader stages)
3598*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3599*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pStages-00731");
3600*b7893ccfSSadaf Ebrahimi
3601*b7893ccfSSadaf Ebrahimi // Pass an invalid pTessellationState (bad sType)
3602*b7893ccfSSadaf Ebrahimi tsci_bad.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3603*b7893ccfSSadaf Ebrahimi p_tsci = &tsci_bad;
3604*b7893ccfSSadaf Ebrahimi shader_stages = {tcs.GetStageCreateInfo(), tes.GetStageCreateInfo()};
3605*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3606*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineTessellationStateCreateInfo-sType-sType");
3607*b7893ccfSSadaf Ebrahimi
3608*b7893ccfSSadaf Ebrahimi // Pass out-of-range patchControlPoints
3609*b7893ccfSSadaf Ebrahimi p_iasci = &iasci;
3610*b7893ccfSSadaf Ebrahimi tsci_bad = tsci;
3611*b7893ccfSSadaf Ebrahimi tsci_bad.patchControlPoints = 0;
3612*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3613*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214");
3614*b7893ccfSSadaf Ebrahimi
3615*b7893ccfSSadaf Ebrahimi tsci_bad.patchControlPoints = m_device->props.limits.maxTessellationPatchSize + 1;
3616*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3617*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214");
3618*b7893ccfSSadaf Ebrahimi
3619*b7893ccfSSadaf Ebrahimi p_tsci = &tsci;
3620*b7893ccfSSadaf Ebrahimi // Pass an invalid primitive topology
3621*b7893ccfSSadaf Ebrahimi iasci_bad = iasci;
3622*b7893ccfSSadaf Ebrahimi iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
3623*b7893ccfSSadaf Ebrahimi p_iasci = &iasci_bad;
3624*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3625*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pStages-00736");
3626*b7893ccfSSadaf Ebrahimi }
3627*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineAttribBindingConflict)3628*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
3629*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3630*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a vertex attribute setup where multiple bindings provide the same location");
3631*b7893ccfSSadaf Ebrahimi
3632*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3633*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3634*b7893ccfSSadaf Ebrahimi
3635*b7893ccfSSadaf Ebrahimi /* Two binding descriptions for binding 0 */
3636*b7893ccfSSadaf Ebrahimi VkVertexInputBindingDescription input_bindings[2];
3637*b7893ccfSSadaf Ebrahimi memset(input_bindings, 0, sizeof(input_bindings));
3638*b7893ccfSSadaf Ebrahimi
3639*b7893ccfSSadaf Ebrahimi VkVertexInputAttributeDescription input_attrib;
3640*b7893ccfSSadaf Ebrahimi memset(&input_attrib, 0, sizeof(input_attrib));
3641*b7893ccfSSadaf Ebrahimi input_attrib.format = VK_FORMAT_R32_SFLOAT;
3642*b7893ccfSSadaf Ebrahimi
3643*b7893ccfSSadaf Ebrahimi char const *vsSource =
3644*b7893ccfSSadaf Ebrahimi "#version 450\n"
3645*b7893ccfSSadaf Ebrahimi "\n"
3646*b7893ccfSSadaf Ebrahimi "layout(location=0) in float x;\n" /* attrib provided float */
3647*b7893ccfSSadaf Ebrahimi "void main(){\n"
3648*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(x);\n"
3649*b7893ccfSSadaf Ebrahimi "}\n";
3650*b7893ccfSSadaf Ebrahimi
3651*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3652*b7893ccfSSadaf Ebrahimi
3653*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
3654*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3655*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
3656*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexBindingDescriptions = input_bindings;
3657*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexBindingDescriptionCount = 2;
3658*b7893ccfSSadaf Ebrahimi helper.vi_ci_.pVertexAttributeDescriptions = &input_attrib;
3659*b7893ccfSSadaf Ebrahimi helper.vi_ci_.vertexAttributeDescriptionCount = 1;
3660*b7893ccfSSadaf Ebrahimi };
3661*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetUnexpectedError("VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-00616 ");
3662*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3663*b7893ccfSSadaf Ebrahimi "Duplicate vertex input binding descriptions for binding 0");
3664*b7893ccfSSadaf Ebrahimi }
3665*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineFragmentOutputNotWritten)3666*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
3667*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3668*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a fragment shader which does not provide an output for one of the pipeline's color "
3669*b7893ccfSSadaf Ebrahimi "attachments");
3670*b7893ccfSSadaf Ebrahimi
3671*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3672*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3673*b7893ccfSSadaf Ebrahimi
3674*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, bindStateMinimalShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3675*b7893ccfSSadaf Ebrahimi
3676*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3677*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3678*b7893ccfSSadaf Ebrahimi helper.cb_attachments_.colorWriteMask = 1;
3679*b7893ccfSSadaf Ebrahimi };
3680*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_WARNING_BIT_EXT,
3681*b7893ccfSSadaf Ebrahimi "Attachment 0 not written by fragment shader");
3682*b7893ccfSSadaf Ebrahimi }
3683*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineFragmentOutputNotConsumed)3684*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
3685*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3686*b7893ccfSSadaf Ebrahimi "Test that a warning is produced for a fragment shader which provides a spurious output with no matching attachment");
3687*b7893ccfSSadaf Ebrahimi
3688*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3689*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3690*b7893ccfSSadaf Ebrahimi
3691*b7893ccfSSadaf Ebrahimi char const *fsSource =
3692*b7893ccfSSadaf Ebrahimi "#version 450\n"
3693*b7893ccfSSadaf Ebrahimi "\n"
3694*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 x;\n"
3695*b7893ccfSSadaf Ebrahimi "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
3696*b7893ccfSSadaf Ebrahimi "void main(){\n"
3697*b7893ccfSSadaf Ebrahimi " x = vec4(1);\n"
3698*b7893ccfSSadaf Ebrahimi " y = vec4(1);\n"
3699*b7893ccfSSadaf Ebrahimi "}\n";
3700*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3701*b7893ccfSSadaf Ebrahimi
3702*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3703*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3704*b7893ccfSSadaf Ebrahimi };
3705*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_WARNING_BIT_EXT,
3706*b7893ccfSSadaf Ebrahimi "fragment shader writes to output location 1 with no matching attachment");
3707*b7893ccfSSadaf Ebrahimi }
3708*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineFragmentNoOutputLocation0ButAlphaToCoverageEnabled)3709*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineFragmentNoOutputLocation0ButAlphaToCoverageEnabled) {
3710*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that an error is produced when alpha to coverage is enabled but no output at location 0 is declared.");
3711*b7893ccfSSadaf Ebrahimi
3712*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3713*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget(0u));
3714*b7893ccfSSadaf Ebrahimi
3715*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, bindStateMinimalShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3716*b7893ccfSSadaf Ebrahimi
3717*b7893ccfSSadaf Ebrahimi VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
3718*b7893ccfSSadaf Ebrahimi ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
3719*b7893ccfSSadaf Ebrahimi ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
3720*b7893ccfSSadaf Ebrahimi ms_state_ci.alphaToCoverageEnable = VK_TRUE;
3721*b7893ccfSSadaf Ebrahimi
3722*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3723*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3724*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_ = ms_state_ci;
3725*b7893ccfSSadaf Ebrahimi };
3726*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
3727*b7893ccfSSadaf Ebrahimi *this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3728*b7893ccfSSadaf Ebrahimi "fragment shader doesn't declare alpha output at location 0 even though alpha to coverage is enabled.");
3729*b7893ccfSSadaf Ebrahimi }
3730*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineFragmentNoAlphaLocation0ButAlphaToCoverageEnabled)3731*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineFragmentNoAlphaLocation0ButAlphaToCoverageEnabled) {
3732*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3733*b7893ccfSSadaf Ebrahimi "Test that an error is produced when alpha to coverage is enabled but output at location 0 doesn't have alpha channel.");
3734*b7893ccfSSadaf Ebrahimi
3735*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3736*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget(0u));
3737*b7893ccfSSadaf Ebrahimi
3738*b7893ccfSSadaf Ebrahimi char const *fsSource =
3739*b7893ccfSSadaf Ebrahimi "#version 450\n"
3740*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec3 x;\n"
3741*b7893ccfSSadaf Ebrahimi "\n"
3742*b7893ccfSSadaf Ebrahimi "void main(){\n"
3743*b7893ccfSSadaf Ebrahimi " x = vec3(1);\n"
3744*b7893ccfSSadaf Ebrahimi "}\n";
3745*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3746*b7893ccfSSadaf Ebrahimi
3747*b7893ccfSSadaf Ebrahimi VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
3748*b7893ccfSSadaf Ebrahimi ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
3749*b7893ccfSSadaf Ebrahimi ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
3750*b7893ccfSSadaf Ebrahimi ms_state_ci.alphaToCoverageEnable = VK_TRUE;
3751*b7893ccfSSadaf Ebrahimi
3752*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3753*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3754*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_ = ms_state_ci;
3755*b7893ccfSSadaf Ebrahimi };
3756*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
3757*b7893ccfSSadaf Ebrahimi *this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3758*b7893ccfSSadaf Ebrahimi "fragment shader doesn't declare alpha output at location 0 even though alpha to coverage is enabled.");
3759*b7893ccfSSadaf Ebrahimi }
3760*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineFragmentOutputTypeMismatch)3761*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
3762*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3763*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a mismatch between the fundamental type of an fragment shader output variable, and the "
3764*b7893ccfSSadaf Ebrahimi "format of the corresponding attachment");
3765*b7893ccfSSadaf Ebrahimi
3766*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3767*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3768*b7893ccfSSadaf Ebrahimi
3769*b7893ccfSSadaf Ebrahimi char const *fsSource =
3770*b7893ccfSSadaf Ebrahimi "#version 450\n"
3771*b7893ccfSSadaf Ebrahimi "\n"
3772*b7893ccfSSadaf Ebrahimi "layout(location=0) out ivec4 x;\n" /* not UNORM */
3773*b7893ccfSSadaf Ebrahimi "void main(){\n"
3774*b7893ccfSSadaf Ebrahimi " x = ivec4(1);\n"
3775*b7893ccfSSadaf Ebrahimi "}\n";
3776*b7893ccfSSadaf Ebrahimi
3777*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3778*b7893ccfSSadaf Ebrahimi
3779*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3780*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3781*b7893ccfSSadaf Ebrahimi };
3782*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_WARNING_BIT_EXT,
3783*b7893ccfSSadaf Ebrahimi "does not match fragment shader output type");
3784*b7893ccfSSadaf Ebrahimi }
3785*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineExceedMaxVertexOutputComponents)3786*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineExceedMaxVertexOutputComponents) {
3787*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3788*b7893ccfSSadaf Ebrahimi "Test that an error is produced when the number of output components from the vertex stage exceeds the device limit");
3789*b7893ccfSSadaf Ebrahimi
3790*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3791*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3792*b7893ccfSSadaf Ebrahimi
3793*b7893ccfSSadaf Ebrahimi for (int overflow = 0; overflow < 2; ++overflow) {
3794*b7893ccfSSadaf Ebrahimi m_errorMonitor->Reset();
3795*b7893ccfSSadaf Ebrahimi
3796*b7893ccfSSadaf Ebrahimi const uint32_t maxVsOutComp = m_device->props.limits.maxVertexOutputComponents + overflow;
3797*b7893ccfSSadaf Ebrahimi std::string vsSourceStr = "#version 450\n\n";
3798*b7893ccfSSadaf Ebrahimi const uint32_t numVec4 = maxVsOutComp / 4;
3799*b7893ccfSSadaf Ebrahimi uint32_t location = 0;
3800*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < numVec4; i++) {
3801*b7893ccfSSadaf Ebrahimi vsSourceStr += "layout(location=" + std::to_string(location) + ") out vec4 v" + std::to_string(i) + ";\n";
3802*b7893ccfSSadaf Ebrahimi location += 1;
3803*b7893ccfSSadaf Ebrahimi }
3804*b7893ccfSSadaf Ebrahimi const uint32_t remainder = maxVsOutComp % 4;
3805*b7893ccfSSadaf Ebrahimi if (remainder != 0) {
3806*b7893ccfSSadaf Ebrahimi if (remainder == 1) {
3807*b7893ccfSSadaf Ebrahimi vsSourceStr += "layout(location=" + std::to_string(location) + ") out float" + " vn;\n";
3808*b7893ccfSSadaf Ebrahimi } else {
3809*b7893ccfSSadaf Ebrahimi vsSourceStr += "layout(location=" + std::to_string(location) + ") out vec" + std::to_string(remainder) + " vn;\n";
3810*b7893ccfSSadaf Ebrahimi }
3811*b7893ccfSSadaf Ebrahimi location += 1;
3812*b7893ccfSSadaf Ebrahimi }
3813*b7893ccfSSadaf Ebrahimi vsSourceStr +=
3814*b7893ccfSSadaf Ebrahimi "void main(){\n"
3815*b7893ccfSSadaf Ebrahimi "}\n";
3816*b7893ccfSSadaf Ebrahimi
3817*b7893ccfSSadaf Ebrahimi std::string fsSourceStr =
3818*b7893ccfSSadaf Ebrahimi "#version 450\n"
3819*b7893ccfSSadaf Ebrahimi "\n"
3820*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
3821*b7893ccfSSadaf Ebrahimi "\n"
3822*b7893ccfSSadaf Ebrahimi "void main(){\n"
3823*b7893ccfSSadaf Ebrahimi " color = vec4(1);\n"
3824*b7893ccfSSadaf Ebrahimi "}\n";
3825*b7893ccfSSadaf Ebrahimi
3826*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT, this);
3827*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
3828*b7893ccfSSadaf Ebrahimi
3829*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3830*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3831*b7893ccfSSadaf Ebrahimi };
3832*b7893ccfSSadaf Ebrahimi if (overflow) {
3833*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_WARNING_BIT_EXT,
3834*b7893ccfSSadaf Ebrahimi "Vertex shader exceeds VkPhysicalDeviceLimits::maxVertexOutputComponents");
3835*b7893ccfSSadaf Ebrahimi } else {
3836*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_WARNING_BIT_EXT, "", true);
3837*b7893ccfSSadaf Ebrahimi }
3838*b7893ccfSSadaf Ebrahimi }
3839*b7893ccfSSadaf Ebrahimi }
3840*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineExceedMaxTessellationControlInputOutputComponents)3841*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineExceedMaxTessellationControlInputOutputComponents) {
3842*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3843*b7893ccfSSadaf Ebrahimi "Test that errors are produced when the number of per-vertex input and/or output components to the tessellation control "
3844*b7893ccfSSadaf Ebrahimi "stage exceeds the device limit");
3845*b7893ccfSSadaf Ebrahimi
3846*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3847*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3848*b7893ccfSSadaf Ebrahimi
3849*b7893ccfSSadaf Ebrahimi for (int overflow = 0; overflow < 2; ++overflow) {
3850*b7893ccfSSadaf Ebrahimi m_errorMonitor->Reset();
3851*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures feat;
3852*b7893ccfSSadaf Ebrahimi vkGetPhysicalDeviceFeatures(gpu(), &feat);
3853*b7893ccfSSadaf Ebrahimi if (!feat.tessellationShader) {
3854*b7893ccfSSadaf Ebrahimi printf("%s tessellation shader stage(s) unsupported.\n", kSkipPrefix);
3855*b7893ccfSSadaf Ebrahimi return;
3856*b7893ccfSSadaf Ebrahimi }
3857*b7893ccfSSadaf Ebrahimi
3858*b7893ccfSSadaf Ebrahimi // Tessellation control stage
3859*b7893ccfSSadaf Ebrahimi std::string tcsSourceStr =
3860*b7893ccfSSadaf Ebrahimi "#version 450\n"
3861*b7893ccfSSadaf Ebrahimi "\n";
3862*b7893ccfSSadaf Ebrahimi // Input components
3863*b7893ccfSSadaf Ebrahimi const uint32_t maxTescInComp = m_device->props.limits.maxTessellationControlPerVertexInputComponents + overflow;
3864*b7893ccfSSadaf Ebrahimi const uint32_t numInVec4 = maxTescInComp / 4;
3865*b7893ccfSSadaf Ebrahimi uint32_t inLocation = 0;
3866*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < numInVec4; i++) {
3867*b7893ccfSSadaf Ebrahimi tcsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in vec4 v" + std::to_string(i) + "In[];\n";
3868*b7893ccfSSadaf Ebrahimi inLocation += 1;
3869*b7893ccfSSadaf Ebrahimi }
3870*b7893ccfSSadaf Ebrahimi const uint32_t inRemainder = maxTescInComp % 4;
3871*b7893ccfSSadaf Ebrahimi if (inRemainder != 0) {
3872*b7893ccfSSadaf Ebrahimi if (inRemainder == 1) {
3873*b7893ccfSSadaf Ebrahimi tcsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in float" + " vnIn[];\n";
3874*b7893ccfSSadaf Ebrahimi } else {
3875*b7893ccfSSadaf Ebrahimi tcsSourceStr +=
3876*b7893ccfSSadaf Ebrahimi "layout(location=" + std::to_string(inLocation) + ") in vec" + std::to_string(inRemainder) + " vnIn[];\n";
3877*b7893ccfSSadaf Ebrahimi }
3878*b7893ccfSSadaf Ebrahimi inLocation += 1;
3879*b7893ccfSSadaf Ebrahimi }
3880*b7893ccfSSadaf Ebrahimi
3881*b7893ccfSSadaf Ebrahimi // Output components
3882*b7893ccfSSadaf Ebrahimi const uint32_t maxTescOutComp = m_device->props.limits.maxTessellationControlPerVertexOutputComponents + overflow;
3883*b7893ccfSSadaf Ebrahimi const uint32_t numOutVec4 = maxTescOutComp / 4;
3884*b7893ccfSSadaf Ebrahimi uint32_t outLocation = 0;
3885*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < numOutVec4; i++) {
3886*b7893ccfSSadaf Ebrahimi tcsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out vec4 v" + std::to_string(i) + "Out[3];\n";
3887*b7893ccfSSadaf Ebrahimi outLocation += 1;
3888*b7893ccfSSadaf Ebrahimi }
3889*b7893ccfSSadaf Ebrahimi const uint32_t outRemainder = maxTescOutComp % 4;
3890*b7893ccfSSadaf Ebrahimi if (outRemainder != 0) {
3891*b7893ccfSSadaf Ebrahimi if (outRemainder == 1) {
3892*b7893ccfSSadaf Ebrahimi tcsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out float" + " vnOut[3];\n";
3893*b7893ccfSSadaf Ebrahimi } else {
3894*b7893ccfSSadaf Ebrahimi tcsSourceStr +=
3895*b7893ccfSSadaf Ebrahimi "layout(location=" + std::to_string(outLocation) + ") out vec" + std::to_string(outRemainder) + " vnOut[3];\n";
3896*b7893ccfSSadaf Ebrahimi }
3897*b7893ccfSSadaf Ebrahimi outLocation += 1;
3898*b7893ccfSSadaf Ebrahimi }
3899*b7893ccfSSadaf Ebrahimi
3900*b7893ccfSSadaf Ebrahimi tcsSourceStr += "layout(vertices=3) out;\n";
3901*b7893ccfSSadaf Ebrahimi // Finalize
3902*b7893ccfSSadaf Ebrahimi tcsSourceStr +=
3903*b7893ccfSSadaf Ebrahimi "\n"
3904*b7893ccfSSadaf Ebrahimi "void main(){\n"
3905*b7893ccfSSadaf Ebrahimi "}\n";
3906*b7893ccfSSadaf Ebrahimi
3907*b7893ccfSSadaf Ebrahimi VkShaderObj tcs(m_device, tcsSourceStr.c_str(), VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
3908*b7893ccfSSadaf Ebrahimi VkShaderObj tes(m_device, bindStateTeshaderText, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
3909*b7893ccfSSadaf Ebrahimi
3910*b7893ccfSSadaf Ebrahimi VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = {};
3911*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
3912*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.pNext = NULL;
3913*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.flags = 0;
3914*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
3915*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
3916*b7893ccfSSadaf Ebrahimi
3917*b7893ccfSSadaf Ebrahimi VkPipelineTessellationStateCreateInfo tessInfo = {};
3918*b7893ccfSSadaf Ebrahimi tessInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
3919*b7893ccfSSadaf Ebrahimi tessInfo.pNext = NULL;
3920*b7893ccfSSadaf Ebrahimi tessInfo.flags = 0;
3921*b7893ccfSSadaf Ebrahimi tessInfo.patchControlPoints = 3;
3922*b7893ccfSSadaf Ebrahimi
3923*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetUnexpectedError("UNASSIGNED-CoreValidation-Shader-InputNotProduced");
3924*b7893ccfSSadaf Ebrahimi
3925*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
3926*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), tcs.GetStageCreateInfo(), tes.GetStageCreateInfo(),
3927*b7893ccfSSadaf Ebrahimi helper.fs_->GetStageCreateInfo()};
3928*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pTessellationState = &tessInfo;
3929*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pInputAssemblyState = &inputAssemblyInfo;
3930*b7893ccfSSadaf Ebrahimi };
3931*b7893ccfSSadaf Ebrahimi if (overflow) {
3932*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
3933*b7893ccfSSadaf Ebrahimi *this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3934*b7893ccfSSadaf Ebrahimi vector<string>{
3935*b7893ccfSSadaf Ebrahimi "Tessellation control shader exceeds VkPhysicalDeviceLimits::maxTessellationControlPerVertexInputComponents",
3936*b7893ccfSSadaf Ebrahimi "Tessellation control shader exceeds VkPhysicalDeviceLimits::maxTessellationControlPerVertexOutputComponents"});
3937*b7893ccfSSadaf Ebrahimi } else {
3938*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "", true);
3939*b7893ccfSSadaf Ebrahimi }
3940*b7893ccfSSadaf Ebrahimi }
3941*b7893ccfSSadaf Ebrahimi }
3942*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineExceedMaxTessellationEvaluationInputOutputComponents)3943*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineExceedMaxTessellationEvaluationInputOutputComponents) {
3944*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
3945*b7893ccfSSadaf Ebrahimi "Test that errors are produced when the number of input and/or output components to the tessellation evaluation stage "
3946*b7893ccfSSadaf Ebrahimi "exceeds the device limit");
3947*b7893ccfSSadaf Ebrahimi
3948*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
3949*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3950*b7893ccfSSadaf Ebrahimi
3951*b7893ccfSSadaf Ebrahimi for (int overflow = 0; overflow < 2; ++overflow) {
3952*b7893ccfSSadaf Ebrahimi m_errorMonitor->Reset();
3953*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures feat;
3954*b7893ccfSSadaf Ebrahimi vkGetPhysicalDeviceFeatures(gpu(), &feat);
3955*b7893ccfSSadaf Ebrahimi if (!feat.tessellationShader) {
3956*b7893ccfSSadaf Ebrahimi printf("%s tessellation shader stage(s) unsupported.\n", kSkipPrefix);
3957*b7893ccfSSadaf Ebrahimi return;
3958*b7893ccfSSadaf Ebrahimi }
3959*b7893ccfSSadaf Ebrahimi
3960*b7893ccfSSadaf Ebrahimi // Tessellation evaluation stage
3961*b7893ccfSSadaf Ebrahimi std::string tesSourceStr =
3962*b7893ccfSSadaf Ebrahimi "#version 450\n"
3963*b7893ccfSSadaf Ebrahimi "\n"
3964*b7893ccfSSadaf Ebrahimi "layout (triangles) in;\n"
3965*b7893ccfSSadaf Ebrahimi "\n";
3966*b7893ccfSSadaf Ebrahimi // Input components
3967*b7893ccfSSadaf Ebrahimi const uint32_t maxTeseInComp = m_device->props.limits.maxTessellationEvaluationInputComponents + overflow;
3968*b7893ccfSSadaf Ebrahimi const uint32_t numInVec4 = maxTeseInComp / 4;
3969*b7893ccfSSadaf Ebrahimi uint32_t inLocation = 0;
3970*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < numInVec4; i++) {
3971*b7893ccfSSadaf Ebrahimi tesSourceStr += "layout(location=" + std::to_string(inLocation) + ") in vec4 v" + std::to_string(i) + "In[];\n";
3972*b7893ccfSSadaf Ebrahimi inLocation += 1;
3973*b7893ccfSSadaf Ebrahimi }
3974*b7893ccfSSadaf Ebrahimi const uint32_t inRemainder = maxTeseInComp % 4;
3975*b7893ccfSSadaf Ebrahimi if (inRemainder != 0) {
3976*b7893ccfSSadaf Ebrahimi if (inRemainder == 1) {
3977*b7893ccfSSadaf Ebrahimi tesSourceStr += "layout(location=" + std::to_string(inLocation) + ") in float" + " vnIn[];\n";
3978*b7893ccfSSadaf Ebrahimi } else {
3979*b7893ccfSSadaf Ebrahimi tesSourceStr +=
3980*b7893ccfSSadaf Ebrahimi "layout(location=" + std::to_string(inLocation) + ") in vec" + std::to_string(inRemainder) + " vnIn[];\n";
3981*b7893ccfSSadaf Ebrahimi }
3982*b7893ccfSSadaf Ebrahimi inLocation += 1;
3983*b7893ccfSSadaf Ebrahimi }
3984*b7893ccfSSadaf Ebrahimi
3985*b7893ccfSSadaf Ebrahimi // Output components
3986*b7893ccfSSadaf Ebrahimi const uint32_t maxTeseOutComp = m_device->props.limits.maxTessellationEvaluationOutputComponents + overflow;
3987*b7893ccfSSadaf Ebrahimi const uint32_t numOutVec4 = maxTeseOutComp / 4;
3988*b7893ccfSSadaf Ebrahimi uint32_t outLocation = 0;
3989*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < numOutVec4; i++) {
3990*b7893ccfSSadaf Ebrahimi tesSourceStr += "layout(location=" + std::to_string(outLocation) + ") out vec4 v" + std::to_string(i) + "Out;\n";
3991*b7893ccfSSadaf Ebrahimi outLocation += 1;
3992*b7893ccfSSadaf Ebrahimi }
3993*b7893ccfSSadaf Ebrahimi const uint32_t outRemainder = maxTeseOutComp % 4;
3994*b7893ccfSSadaf Ebrahimi if (outRemainder != 0) {
3995*b7893ccfSSadaf Ebrahimi if (outRemainder == 1) {
3996*b7893ccfSSadaf Ebrahimi tesSourceStr += "layout(location=" + std::to_string(outLocation) + ") out float" + " vnOut;\n";
3997*b7893ccfSSadaf Ebrahimi } else {
3998*b7893ccfSSadaf Ebrahimi tesSourceStr +=
3999*b7893ccfSSadaf Ebrahimi "layout(location=" + std::to_string(outLocation) + ") out vec" + std::to_string(outRemainder) + " vnOut;\n";
4000*b7893ccfSSadaf Ebrahimi }
4001*b7893ccfSSadaf Ebrahimi outLocation += 1;
4002*b7893ccfSSadaf Ebrahimi }
4003*b7893ccfSSadaf Ebrahimi
4004*b7893ccfSSadaf Ebrahimi // Finalize
4005*b7893ccfSSadaf Ebrahimi tesSourceStr +=
4006*b7893ccfSSadaf Ebrahimi "\n"
4007*b7893ccfSSadaf Ebrahimi "void main(){\n"
4008*b7893ccfSSadaf Ebrahimi "}\n";
4009*b7893ccfSSadaf Ebrahimi
4010*b7893ccfSSadaf Ebrahimi VkShaderObj tcs(m_device, bindStateTscShaderText, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
4011*b7893ccfSSadaf Ebrahimi VkShaderObj tes(m_device, tesSourceStr.c_str(), VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
4012*b7893ccfSSadaf Ebrahimi
4013*b7893ccfSSadaf Ebrahimi VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = {};
4014*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
4015*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.pNext = NULL;
4016*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.flags = 0;
4017*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
4018*b7893ccfSSadaf Ebrahimi inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
4019*b7893ccfSSadaf Ebrahimi
4020*b7893ccfSSadaf Ebrahimi VkPipelineTessellationStateCreateInfo tessInfo = {};
4021*b7893ccfSSadaf Ebrahimi tessInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
4022*b7893ccfSSadaf Ebrahimi tessInfo.pNext = NULL;
4023*b7893ccfSSadaf Ebrahimi tessInfo.flags = 0;
4024*b7893ccfSSadaf Ebrahimi tessInfo.patchControlPoints = 3;
4025*b7893ccfSSadaf Ebrahimi
4026*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetUnexpectedError("UNASSIGNED-CoreValidation-Shader-InputNotProduced");
4027*b7893ccfSSadaf Ebrahimi
4028*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
4029*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), tcs.GetStageCreateInfo(), tes.GetStageCreateInfo(),
4030*b7893ccfSSadaf Ebrahimi helper.fs_->GetStageCreateInfo()};
4031*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pTessellationState = &tessInfo;
4032*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pInputAssemblyState = &inputAssemblyInfo;
4033*b7893ccfSSadaf Ebrahimi };
4034*b7893ccfSSadaf Ebrahimi if (overflow) {
4035*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
4036*b7893ccfSSadaf Ebrahimi *this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4037*b7893ccfSSadaf Ebrahimi vector<string>{
4038*b7893ccfSSadaf Ebrahimi "Tessellation evaluation shader exceeds VkPhysicalDeviceLimits::maxTessellationEvaluationInputComponents",
4039*b7893ccfSSadaf Ebrahimi "Tessellation evaluation shader exceeds VkPhysicalDeviceLimits::maxTessellationEvaluationOutputComponents"});
4040*b7893ccfSSadaf Ebrahimi } else {
4041*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "", true);
4042*b7893ccfSSadaf Ebrahimi }
4043*b7893ccfSSadaf Ebrahimi }
4044*b7893ccfSSadaf Ebrahimi }
4045*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineExceedMaxGeometryInputOutputComponents)4046*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineExceedMaxGeometryInputOutputComponents) {
4047*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
4048*b7893ccfSSadaf Ebrahimi "Test that errors are produced when the number of input and/or output components to the geometry stage exceeds the device "
4049*b7893ccfSSadaf Ebrahimi "limit");
4050*b7893ccfSSadaf Ebrahimi
4051*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4052*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4053*b7893ccfSSadaf Ebrahimi
4054*b7893ccfSSadaf Ebrahimi for (int overflow = 0; overflow < 2; ++overflow) {
4055*b7893ccfSSadaf Ebrahimi m_errorMonitor->Reset();
4056*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures feat;
4057*b7893ccfSSadaf Ebrahimi vkGetPhysicalDeviceFeatures(gpu(), &feat);
4058*b7893ccfSSadaf Ebrahimi if (!feat.geometryShader) {
4059*b7893ccfSSadaf Ebrahimi printf("%s geometry shader stage unsupported.\n", kSkipPrefix);
4060*b7893ccfSSadaf Ebrahimi return;
4061*b7893ccfSSadaf Ebrahimi }
4062*b7893ccfSSadaf Ebrahimi
4063*b7893ccfSSadaf Ebrahimi std::string gsSourceStr =
4064*b7893ccfSSadaf Ebrahimi "#version 450\n"
4065*b7893ccfSSadaf Ebrahimi "\n"
4066*b7893ccfSSadaf Ebrahimi "layout(triangles) in;\n"
4067*b7893ccfSSadaf Ebrahimi "layout(invocations=1) in;\n";
4068*b7893ccfSSadaf Ebrahimi
4069*b7893ccfSSadaf Ebrahimi // Input components
4070*b7893ccfSSadaf Ebrahimi const uint32_t maxGeomInComp = m_device->props.limits.maxGeometryInputComponents + overflow;
4071*b7893ccfSSadaf Ebrahimi const uint32_t numInVec4 = maxGeomInComp / 4;
4072*b7893ccfSSadaf Ebrahimi uint32_t inLocation = 0;
4073*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < numInVec4; i++) {
4074*b7893ccfSSadaf Ebrahimi gsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in vec4 v" + std::to_string(i) + "In[];\n";
4075*b7893ccfSSadaf Ebrahimi inLocation += 1;
4076*b7893ccfSSadaf Ebrahimi }
4077*b7893ccfSSadaf Ebrahimi const uint32_t inRemainder = maxGeomInComp % 4;
4078*b7893ccfSSadaf Ebrahimi if (inRemainder != 0) {
4079*b7893ccfSSadaf Ebrahimi if (inRemainder == 1) {
4080*b7893ccfSSadaf Ebrahimi gsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in float" + " vnIn[];\n";
4081*b7893ccfSSadaf Ebrahimi } else {
4082*b7893ccfSSadaf Ebrahimi gsSourceStr +=
4083*b7893ccfSSadaf Ebrahimi "layout(location=" + std::to_string(inLocation) + ") in vec" + std::to_string(inRemainder) + " vnIn[];\n";
4084*b7893ccfSSadaf Ebrahimi }
4085*b7893ccfSSadaf Ebrahimi inLocation += 1;
4086*b7893ccfSSadaf Ebrahimi }
4087*b7893ccfSSadaf Ebrahimi
4088*b7893ccfSSadaf Ebrahimi // Output components
4089*b7893ccfSSadaf Ebrahimi const uint32_t maxGeomOutComp = m_device->props.limits.maxGeometryOutputComponents + overflow;
4090*b7893ccfSSadaf Ebrahimi const uint32_t numOutVec4 = maxGeomOutComp / 4;
4091*b7893ccfSSadaf Ebrahimi uint32_t outLocation = 0;
4092*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < numOutVec4; i++) {
4093*b7893ccfSSadaf Ebrahimi gsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out vec4 v" + std::to_string(i) + "Out;\n";
4094*b7893ccfSSadaf Ebrahimi outLocation += 1;
4095*b7893ccfSSadaf Ebrahimi }
4096*b7893ccfSSadaf Ebrahimi const uint32_t outRemainder = maxGeomOutComp % 4;
4097*b7893ccfSSadaf Ebrahimi if (outRemainder != 0) {
4098*b7893ccfSSadaf Ebrahimi if (outRemainder == 1) {
4099*b7893ccfSSadaf Ebrahimi gsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out float" + " vnOut;\n";
4100*b7893ccfSSadaf Ebrahimi } else {
4101*b7893ccfSSadaf Ebrahimi gsSourceStr +=
4102*b7893ccfSSadaf Ebrahimi "layout(location=" + std::to_string(outLocation) + ") out vec" + std::to_string(outRemainder) + " vnOut;\n";
4103*b7893ccfSSadaf Ebrahimi }
4104*b7893ccfSSadaf Ebrahimi outLocation += 1;
4105*b7893ccfSSadaf Ebrahimi }
4106*b7893ccfSSadaf Ebrahimi
4107*b7893ccfSSadaf Ebrahimi // Finalize
4108*b7893ccfSSadaf Ebrahimi int max_vertices = overflow ? (m_device->props.limits.maxGeometryTotalOutputComponents / maxGeomOutComp + 1) : 1;
4109*b7893ccfSSadaf Ebrahimi gsSourceStr += "layout(triangle_strip, max_vertices = " + std::to_string(max_vertices) +
4110*b7893ccfSSadaf Ebrahimi ") out;\n"
4111*b7893ccfSSadaf Ebrahimi "\n"
4112*b7893ccfSSadaf Ebrahimi "void main(){\n"
4113*b7893ccfSSadaf Ebrahimi "}\n";
4114*b7893ccfSSadaf Ebrahimi
4115*b7893ccfSSadaf Ebrahimi VkShaderObj gs(m_device, gsSourceStr.c_str(), VK_SHADER_STAGE_GEOMETRY_BIT, this);
4116*b7893ccfSSadaf Ebrahimi
4117*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetUnexpectedError("UNASSIGNED-CoreValidation-Shader-InputNotProduced");
4118*b7893ccfSSadaf Ebrahimi
4119*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
4120*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), gs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
4121*b7893ccfSSadaf Ebrahimi };
4122*b7893ccfSSadaf Ebrahimi if (overflow) {
4123*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
4124*b7893ccfSSadaf Ebrahimi *this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4125*b7893ccfSSadaf Ebrahimi vector<string>{"Geometry shader exceeds VkPhysicalDeviceLimits::maxGeometryInputComponents",
4126*b7893ccfSSadaf Ebrahimi "Geometry shader exceeds VkPhysicalDeviceLimits::maxGeometryOutputComponents",
4127*b7893ccfSSadaf Ebrahimi "Geometry shader exceeds VkPhysicalDeviceLimits::maxGeometryTotalOutputComponents"});
4128*b7893ccfSSadaf Ebrahimi } else {
4129*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "", true);
4130*b7893ccfSSadaf Ebrahimi }
4131*b7893ccfSSadaf Ebrahimi }
4132*b7893ccfSSadaf Ebrahimi }
4133*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineExceedMaxFragmentInputComponents)4134*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineExceedMaxFragmentInputComponents) {
4135*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
4136*b7893ccfSSadaf Ebrahimi "Test that an error is produced when the number of input components from the fragment stage exceeds the device limit");
4137*b7893ccfSSadaf Ebrahimi
4138*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4139*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4140*b7893ccfSSadaf Ebrahimi
4141*b7893ccfSSadaf Ebrahimi for (int overflow = 0; overflow < 2; ++overflow) {
4142*b7893ccfSSadaf Ebrahimi m_errorMonitor->Reset();
4143*b7893ccfSSadaf Ebrahimi
4144*b7893ccfSSadaf Ebrahimi const uint32_t maxFsInComp = m_device->props.limits.maxFragmentInputComponents + overflow;
4145*b7893ccfSSadaf Ebrahimi std::string fsSourceStr = "#version 450\n\n";
4146*b7893ccfSSadaf Ebrahimi const uint32_t numVec4 = maxFsInComp / 4;
4147*b7893ccfSSadaf Ebrahimi uint32_t location = 0;
4148*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < numVec4; i++) {
4149*b7893ccfSSadaf Ebrahimi fsSourceStr += "layout(location=" + std::to_string(location) + ") in vec4 v" + std::to_string(i) + ";\n";
4150*b7893ccfSSadaf Ebrahimi location += 1;
4151*b7893ccfSSadaf Ebrahimi }
4152*b7893ccfSSadaf Ebrahimi const uint32_t remainder = maxFsInComp % 4;
4153*b7893ccfSSadaf Ebrahimi if (remainder != 0) {
4154*b7893ccfSSadaf Ebrahimi if (remainder == 1) {
4155*b7893ccfSSadaf Ebrahimi fsSourceStr += "layout(location=" + std::to_string(location) + ") in float" + " vn;\n";
4156*b7893ccfSSadaf Ebrahimi } else {
4157*b7893ccfSSadaf Ebrahimi fsSourceStr += "layout(location=" + std::to_string(location) + ") in vec" + std::to_string(remainder) + " vn;\n";
4158*b7893ccfSSadaf Ebrahimi }
4159*b7893ccfSSadaf Ebrahimi location += 1;
4160*b7893ccfSSadaf Ebrahimi }
4161*b7893ccfSSadaf Ebrahimi fsSourceStr +=
4162*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;"
4163*b7893ccfSSadaf Ebrahimi "\n"
4164*b7893ccfSSadaf Ebrahimi "void main(){\n"
4165*b7893ccfSSadaf Ebrahimi " color = vec4(1);\n"
4166*b7893ccfSSadaf Ebrahimi "}\n";
4167*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
4168*b7893ccfSSadaf Ebrahimi
4169*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetUnexpectedError("UNASSIGNED-CoreValidation-Shader-InputNotProduced");
4170*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
4171*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
4172*b7893ccfSSadaf Ebrahimi };
4173*b7893ccfSSadaf Ebrahimi if (overflow) {
4174*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4175*b7893ccfSSadaf Ebrahimi "Fragment shader exceeds "
4176*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceLimits::maxFragmentInputComponents");
4177*b7893ccfSSadaf Ebrahimi } else {
4178*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "", true);
4179*b7893ccfSSadaf Ebrahimi }
4180*b7893ccfSSadaf Ebrahimi }
4181*b7893ccfSSadaf Ebrahimi }
4182*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineExceedMaxGeometryInstanceVertexCount)4183*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineExceedMaxGeometryInstanceVertexCount) {
4184*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
4185*b7893ccfSSadaf Ebrahimi "Test that errors are produced when the number of output vertices/instances in the geometry stage exceeds the device "
4186*b7893ccfSSadaf Ebrahimi "limit");
4187*b7893ccfSSadaf Ebrahimi
4188*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4189*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4190*b7893ccfSSadaf Ebrahimi
4191*b7893ccfSSadaf Ebrahimi for (int overflow = 0; overflow < 2; ++overflow) {
4192*b7893ccfSSadaf Ebrahimi m_errorMonitor->Reset();
4193*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures feat;
4194*b7893ccfSSadaf Ebrahimi vkGetPhysicalDeviceFeatures(gpu(), &feat);
4195*b7893ccfSSadaf Ebrahimi if (!feat.geometryShader) {
4196*b7893ccfSSadaf Ebrahimi printf("%s geometry shader stage unsupported.\n", kSkipPrefix);
4197*b7893ccfSSadaf Ebrahimi return;
4198*b7893ccfSSadaf Ebrahimi }
4199*b7893ccfSSadaf Ebrahimi
4200*b7893ccfSSadaf Ebrahimi std::string gsSourceStr = R"(
4201*b7893ccfSSadaf Ebrahimi OpCapability Geometry
4202*b7893ccfSSadaf Ebrahimi OpMemoryModel Logical GLSL450
4203*b7893ccfSSadaf Ebrahimi OpEntryPoint Geometry %main "main"
4204*b7893ccfSSadaf Ebrahimi OpExecutionMode %main InputPoints
4205*b7893ccfSSadaf Ebrahimi OpExecutionMode %main OutputTriangleStrip
4206*b7893ccfSSadaf Ebrahimi )";
4207*b7893ccfSSadaf Ebrahimi if (overflow) {
4208*b7893ccfSSadaf Ebrahimi gsSourceStr += "OpExecutionMode %main Invocations " +
4209*b7893ccfSSadaf Ebrahimi std::to_string(m_device->props.limits.maxGeometryShaderInvocations + 1) +
4210*b7893ccfSSadaf Ebrahimi "\n\
4211*b7893ccfSSadaf Ebrahimi OpExecutionMode %main OutputVertices " +
4212*b7893ccfSSadaf Ebrahimi std::to_string(m_device->props.limits.maxGeometryOutputVertices + 1);
4213*b7893ccfSSadaf Ebrahimi } else {
4214*b7893ccfSSadaf Ebrahimi gsSourceStr += R"(
4215*b7893ccfSSadaf Ebrahimi OpExecutionMode %main Invocations 1
4216*b7893ccfSSadaf Ebrahimi OpExecutionMode %main OutputVertices 1
4217*b7893ccfSSadaf Ebrahimi )";
4218*b7893ccfSSadaf Ebrahimi }
4219*b7893ccfSSadaf Ebrahimi gsSourceStr += R"(
4220*b7893ccfSSadaf Ebrahimi OpSource GLSL 450
4221*b7893ccfSSadaf Ebrahimi %void = OpTypeVoid
4222*b7893ccfSSadaf Ebrahimi %3 = OpTypeFunction %void
4223*b7893ccfSSadaf Ebrahimi %main = OpFunction %void None %3
4224*b7893ccfSSadaf Ebrahimi %5 = OpLabel
4225*b7893ccfSSadaf Ebrahimi OpReturn
4226*b7893ccfSSadaf Ebrahimi OpFunctionEnd
4227*b7893ccfSSadaf Ebrahimi )";
4228*b7893ccfSSadaf Ebrahimi VkShaderObj gs(m_device, gsSourceStr, VK_SHADER_STAGE_GEOMETRY_BIT, this);
4229*b7893ccfSSadaf Ebrahimi
4230*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
4231*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), gs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
4232*b7893ccfSSadaf Ebrahimi };
4233*b7893ccfSSadaf Ebrahimi if (overflow) {
4234*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4235*b7893ccfSSadaf Ebrahimi vector<string>{"VUID-VkPipelineShaderStageCreateInfo-stage-00714",
4236*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineShaderStageCreateInfo-stage-00715"});
4237*b7893ccfSSadaf Ebrahimi } else {
4238*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "", true);
4239*b7893ccfSSadaf Ebrahimi }
4240*b7893ccfSSadaf Ebrahimi }
4241*b7893ccfSSadaf Ebrahimi }
4242*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineUniformBlockNotProvided)4243*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) {
4244*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
4245*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a shader consuming a uniform block which has no corresponding binding in the pipeline "
4246*b7893ccfSSadaf Ebrahimi "layout");
4247*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout");
4248*b7893ccfSSadaf Ebrahimi
4249*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4250*b7893ccfSSadaf Ebrahimi
4251*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
4252*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, bindStateFragUniformShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4253*b7893ccfSSadaf Ebrahimi
4254*b7893ccfSSadaf Ebrahimi VkPipelineObj pipe(m_device);
4255*b7893ccfSSadaf Ebrahimi pipe.AddShader(&vs);
4256*b7893ccfSSadaf Ebrahimi pipe.AddShader(&fs);
4257*b7893ccfSSadaf Ebrahimi
4258*b7893ccfSSadaf Ebrahimi /* set up CB 0; type is UNORM by default */
4259*b7893ccfSSadaf Ebrahimi pipe.AddDefaultColorAttachment();
4260*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4261*b7893ccfSSadaf Ebrahimi
4262*b7893ccfSSadaf Ebrahimi VkDescriptorSetObj descriptorSet(m_device);
4263*b7893ccfSSadaf Ebrahimi descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
4264*b7893ccfSSadaf Ebrahimi
4265*b7893ccfSSadaf Ebrahimi pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
4266*b7893ccfSSadaf Ebrahimi
4267*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
4268*b7893ccfSSadaf Ebrahimi }
4269*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelinePushConstantsNotInLayout)4270*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) {
4271*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
4272*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a shader consuming push constants which are not provided in the pipeline layout");
4273*b7893ccfSSadaf Ebrahimi
4274*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4275*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4276*b7893ccfSSadaf Ebrahimi
4277*b7893ccfSSadaf Ebrahimi char const *vsSource =
4278*b7893ccfSSadaf Ebrahimi "#version 450\n"
4279*b7893ccfSSadaf Ebrahimi "\n"
4280*b7893ccfSSadaf Ebrahimi "layout(push_constant, std430) uniform foo { float x; } consts;\n"
4281*b7893ccfSSadaf Ebrahimi "void main(){\n"
4282*b7893ccfSSadaf Ebrahimi " gl_Position = vec4(consts.x);\n"
4283*b7893ccfSSadaf Ebrahimi "}\n";
4284*b7893ccfSSadaf Ebrahimi
4285*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
4286*b7893ccfSSadaf Ebrahimi
4287*b7893ccfSSadaf Ebrahimi CreatePipelineHelper pipe(*this);
4288*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
4289*b7893ccfSSadaf Ebrahimi pipe.shader_stages_ = {vs.GetStageCreateInfo(), pipe.fs_->GetStageCreateInfo()};
4290*b7893ccfSSadaf Ebrahimi pipe.InitState();
4291*b7893ccfSSadaf Ebrahimi pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {});
4292*b7893ccfSSadaf Ebrahimi /* should have generated an error -- no push constant ranges provided! */
4293*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout");
4294*b7893ccfSSadaf Ebrahimi pipe.CreateGraphicsPipeline();
4295*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
4296*b7893ccfSSadaf Ebrahimi }
4297*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineInputAttachmentMissing)4298*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) {
4299*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
4300*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a shader consuming an input attachment which is not included in the subpass "
4301*b7893ccfSSadaf Ebrahimi "description");
4302*b7893ccfSSadaf Ebrahimi
4303*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4304*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4305*b7893ccfSSadaf Ebrahimi
4306*b7893ccfSSadaf Ebrahimi char const *fsSource =
4307*b7893ccfSSadaf Ebrahimi "#version 450\n"
4308*b7893ccfSSadaf Ebrahimi "\n"
4309*b7893ccfSSadaf Ebrahimi "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
4310*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
4311*b7893ccfSSadaf Ebrahimi "void main() {\n"
4312*b7893ccfSSadaf Ebrahimi " color = subpassLoad(x);\n"
4313*b7893ccfSSadaf Ebrahimi "}\n";
4314*b7893ccfSSadaf Ebrahimi
4315*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4316*b7893ccfSSadaf Ebrahimi
4317*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
4318*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
4319*b7893ccfSSadaf Ebrahimi helper.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
4320*b7893ccfSSadaf Ebrahimi };
4321*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4322*b7893ccfSSadaf Ebrahimi "consumes input attachment index 0 but not provided in subpass");
4323*b7893ccfSSadaf Ebrahimi }
4324*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineInputAttachmentTypeMismatch)4325*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) {
4326*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
4327*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a shader consuming an input attachment with a format having a different fundamental "
4328*b7893ccfSSadaf Ebrahimi "type");
4329*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4330*b7893ccfSSadaf Ebrahimi "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match");
4331*b7893ccfSSadaf Ebrahimi
4332*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4333*b7893ccfSSadaf Ebrahimi
4334*b7893ccfSSadaf Ebrahimi char const *fsSource =
4335*b7893ccfSSadaf Ebrahimi "#version 450\n"
4336*b7893ccfSSadaf Ebrahimi "\n"
4337*b7893ccfSSadaf Ebrahimi "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
4338*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
4339*b7893ccfSSadaf Ebrahimi "void main() {\n"
4340*b7893ccfSSadaf Ebrahimi " color = subpassLoad(x);\n"
4341*b7893ccfSSadaf Ebrahimi "}\n";
4342*b7893ccfSSadaf Ebrahimi
4343*b7893ccfSSadaf Ebrahimi VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
4344*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4345*b7893ccfSSadaf Ebrahimi
4346*b7893ccfSSadaf Ebrahimi VkPipelineObj pipe(m_device);
4347*b7893ccfSSadaf Ebrahimi pipe.AddShader(&vs);
4348*b7893ccfSSadaf Ebrahimi pipe.AddShader(&fs);
4349*b7893ccfSSadaf Ebrahimi pipe.AddDefaultColorAttachment();
4350*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4351*b7893ccfSSadaf Ebrahimi
4352*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
4353*b7893ccfSSadaf Ebrahimi const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
4354*b7893ccfSSadaf Ebrahimi
4355*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pl(m_device, {&dsl});
4356*b7893ccfSSadaf Ebrahimi
4357*b7893ccfSSadaf Ebrahimi VkAttachmentDescription descs[2] = {
4358*b7893ccfSSadaf Ebrahimi {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
4359*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4360*b7893ccfSSadaf Ebrahimi VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4361*b7893ccfSSadaf Ebrahimi {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
4362*b7893ccfSSadaf Ebrahimi VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
4363*b7893ccfSSadaf Ebrahimi };
4364*b7893ccfSSadaf Ebrahimi VkAttachmentReference color = {
4365*b7893ccfSSadaf Ebrahimi 0,
4366*b7893ccfSSadaf Ebrahimi VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4367*b7893ccfSSadaf Ebrahimi };
4368*b7893ccfSSadaf Ebrahimi VkAttachmentReference input = {
4369*b7893ccfSSadaf Ebrahimi 1,
4370*b7893ccfSSadaf Ebrahimi VK_IMAGE_LAYOUT_GENERAL,
4371*b7893ccfSSadaf Ebrahimi };
4372*b7893ccfSSadaf Ebrahimi
4373*b7893ccfSSadaf Ebrahimi VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
4374*b7893ccfSSadaf Ebrahimi
4375*b7893ccfSSadaf Ebrahimi VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
4376*b7893ccfSSadaf Ebrahimi VkRenderPass rp;
4377*b7893ccfSSadaf Ebrahimi VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4378*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
4379*b7893ccfSSadaf Ebrahimi
4380*b7893ccfSSadaf Ebrahimi // error here.
4381*b7893ccfSSadaf Ebrahimi pipe.CreateVKPipeline(pl.handle(), rp);
4382*b7893ccfSSadaf Ebrahimi
4383*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
4384*b7893ccfSSadaf Ebrahimi
4385*b7893ccfSSadaf Ebrahimi vkDestroyRenderPass(m_device->device(), rp, nullptr);
4386*b7893ccfSSadaf Ebrahimi }
4387*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineInputAttachmentMissingArray)4388*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) {
4389*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
4390*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a shader consuming an input attachment which is not included in the subpass "
4391*b7893ccfSSadaf Ebrahimi "description -- array case");
4392*b7893ccfSSadaf Ebrahimi
4393*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4394*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4395*b7893ccfSSadaf Ebrahimi
4396*b7893ccfSSadaf Ebrahimi char const *fsSource =
4397*b7893ccfSSadaf Ebrahimi "#version 450\n"
4398*b7893ccfSSadaf Ebrahimi "\n"
4399*b7893ccfSSadaf Ebrahimi "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[1];\n"
4400*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
4401*b7893ccfSSadaf Ebrahimi "void main() {\n"
4402*b7893ccfSSadaf Ebrahimi " color = subpassLoad(xs[0]);\n"
4403*b7893ccfSSadaf Ebrahimi "}\n";
4404*b7893ccfSSadaf Ebrahimi
4405*b7893ccfSSadaf Ebrahimi VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4406*b7893ccfSSadaf Ebrahimi
4407*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) {
4408*b7893ccfSSadaf Ebrahimi helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
4409*b7893ccfSSadaf Ebrahimi helper.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
4410*b7893ccfSSadaf Ebrahimi };
4411*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4412*b7893ccfSSadaf Ebrahimi "consumes input attachment index 0 but not provided in subpass");
4413*b7893ccfSSadaf Ebrahimi }
4414*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreateComputePipelineMissingDescriptor)4415*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) {
4416*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION(
4417*b7893ccfSSadaf Ebrahimi "Test that an error is produced for a compute pipeline consuming a descriptor which is not provided in the pipeline "
4418*b7893ccfSSadaf Ebrahimi "layout");
4419*b7893ccfSSadaf Ebrahimi
4420*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4421*b7893ccfSSadaf Ebrahimi
4422*b7893ccfSSadaf Ebrahimi char const *csSource =
4423*b7893ccfSSadaf Ebrahimi "#version 450\n"
4424*b7893ccfSSadaf Ebrahimi "\n"
4425*b7893ccfSSadaf Ebrahimi "layout(local_size_x=1) in;\n"
4426*b7893ccfSSadaf Ebrahimi "layout(set=0, binding=0) buffer block { vec4 x; };\n"
4427*b7893ccfSSadaf Ebrahimi "void main(){\n"
4428*b7893ccfSSadaf Ebrahimi " x = vec4(1);\n"
4429*b7893ccfSSadaf Ebrahimi "}\n";
4430*b7893ccfSSadaf Ebrahimi
4431*b7893ccfSSadaf Ebrahimi CreateComputePipelineHelper pipe(*this);
4432*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
4433*b7893ccfSSadaf Ebrahimi pipe.cs_.reset(new VkShaderObj(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this));
4434*b7893ccfSSadaf Ebrahimi pipe.InitState();
4435*b7893ccfSSadaf Ebrahimi pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {});
4436*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0");
4437*b7893ccfSSadaf Ebrahimi pipe.CreateComputePipeline();
4438*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
4439*b7893ccfSSadaf Ebrahimi }
4440*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreateComputePipelineDescriptorTypeMismatch)4441*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
4442*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a descriptor-backed resource of a mismatched type");
4443*b7893ccfSSadaf Ebrahimi
4444*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
4445*b7893ccfSSadaf Ebrahimi
4446*b7893ccfSSadaf Ebrahimi char const *csSource =
4447*b7893ccfSSadaf Ebrahimi "#version 450\n"
4448*b7893ccfSSadaf Ebrahimi "\n"
4449*b7893ccfSSadaf Ebrahimi "layout(local_size_x=1) in;\n"
4450*b7893ccfSSadaf Ebrahimi "layout(set=0, binding=0) buffer block { vec4 x; };\n"
4451*b7893ccfSSadaf Ebrahimi "void main() {\n"
4452*b7893ccfSSadaf Ebrahimi " x.x = 1.0f;\n"
4453*b7893ccfSSadaf Ebrahimi "}\n";
4454*b7893ccfSSadaf Ebrahimi
4455*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreateComputePipelineHelper &helper) {
4456*b7893ccfSSadaf Ebrahimi helper.cs_.reset(new VkShaderObj(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this));
4457*b7893ccfSSadaf Ebrahimi helper.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};
4458*b7893ccfSSadaf Ebrahimi };
4459*b7893ccfSSadaf Ebrahimi CreateComputePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4460*b7893ccfSSadaf Ebrahimi "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
4461*b7893ccfSSadaf Ebrahimi }
4462*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,MultiplePushDescriptorSets)4463*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, MultiplePushDescriptorSets) {
4464*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Verify an error message for multiple push descriptor sets.");
4465*b7893ccfSSadaf Ebrahimi
4466*b7893ccfSSadaf Ebrahimi if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4467*b7893ccfSSadaf Ebrahimi m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4468*b7893ccfSSadaf Ebrahimi } else {
4469*b7893ccfSSadaf Ebrahimi printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
4470*b7893ccfSSadaf Ebrahimi return;
4471*b7893ccfSSadaf Ebrahimi }
4472*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4473*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
4474*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4475*b7893ccfSSadaf Ebrahimi } else {
4476*b7893ccfSSadaf Ebrahimi printf("%s Push Descriptors Extension not supported, skipping tests\n", kSkipPrefix);
4477*b7893ccfSSadaf Ebrahimi return;
4478*b7893ccfSSadaf Ebrahimi }
4479*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
4480*b7893ccfSSadaf Ebrahimi
4481*b7893ccfSSadaf Ebrahimi auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
4482*b7893ccfSSadaf Ebrahimi if (push_descriptor_prop.maxPushDescriptors < 1) {
4483*b7893ccfSSadaf Ebrahimi // Some implementations report an invalid maxPushDescriptors of 0
4484*b7893ccfSSadaf Ebrahimi printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
4485*b7893ccfSSadaf Ebrahimi return;
4486*b7893ccfSSadaf Ebrahimi }
4487*b7893ccfSSadaf Ebrahimi
4488*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutBinding dsl_binding = {};
4489*b7893ccfSSadaf Ebrahimi dsl_binding.binding = 0;
4490*b7893ccfSSadaf Ebrahimi dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
4491*b7893ccfSSadaf Ebrahimi dsl_binding.descriptorCount = 1;
4492*b7893ccfSSadaf Ebrahimi dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
4493*b7893ccfSSadaf Ebrahimi dsl_binding.pImmutableSamplers = NULL;
4494*b7893ccfSSadaf Ebrahimi
4495*b7893ccfSSadaf Ebrahimi const unsigned int descriptor_set_layout_count = 2;
4496*b7893ccfSSadaf Ebrahimi std::vector<VkDescriptorSetLayoutObj> ds_layouts;
4497*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < descriptor_set_layout_count; ++i) {
4498*b7893ccfSSadaf Ebrahimi dsl_binding.binding = i;
4499*b7893ccfSSadaf Ebrahimi ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding),
4500*b7893ccfSSadaf Ebrahimi VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
4501*b7893ccfSSadaf Ebrahimi }
4502*b7893ccfSSadaf Ebrahimi const auto &ds_vk_layouts = MakeVkHandles<VkDescriptorSetLayout>(ds_layouts);
4503*b7893ccfSSadaf Ebrahimi
4504*b7893ccfSSadaf Ebrahimi VkPipelineLayout pipeline_layout;
4505*b7893ccfSSadaf Ebrahimi VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
4506*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
4507*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pNext = NULL;
4508*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pushConstantRangeCount = 0;
4509*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pPushConstantRanges = NULL;
4510*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.setLayoutCount = ds_vk_layouts.size();
4511*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pSetLayouts = ds_vk_layouts.data();
4512*b7893ccfSSadaf Ebrahimi
4513*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00293");
4514*b7893ccfSSadaf Ebrahimi vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
4515*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
4516*b7893ccfSSadaf Ebrahimi }
4517*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,AMDMixedAttachmentSamplesValidateGraphicsPipeline)4518*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, AMDMixedAttachmentSamplesValidateGraphicsPipeline) {
4519*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Verify an error message for an incorrect graphics pipeline rasterization sample count.");
4520*b7893ccfSSadaf Ebrahimi
4521*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4522*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME)) {
4523*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME);
4524*b7893ccfSSadaf Ebrahimi } else {
4525*b7893ccfSSadaf Ebrahimi printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME);
4526*b7893ccfSSadaf Ebrahimi return;
4527*b7893ccfSSadaf Ebrahimi }
4528*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
4529*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4530*b7893ccfSSadaf Ebrahimi
4531*b7893ccfSSadaf Ebrahimi // Set a mismatched sample count
4532*b7893ccfSSadaf Ebrahimi VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
4533*b7893ccfSSadaf Ebrahimi ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
4534*b7893ccfSSadaf Ebrahimi ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
4535*b7893ccfSSadaf Ebrahimi
4536*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_ = ms_state_ci; };
4537*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4538*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-subpass-01505");
4539*b7893ccfSSadaf Ebrahimi }
4540*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,FramebufferMixedSamplesNV)4541*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, FramebufferMixedSamplesNV) {
4542*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Verify VK_NV_framebuffer_mixed_samples.");
4543*b7893ccfSSadaf Ebrahimi
4544*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4545*b7893ccfSSadaf Ebrahimi
4546*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME)) {
4547*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME);
4548*b7893ccfSSadaf Ebrahimi } else {
4549*b7893ccfSSadaf Ebrahimi printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME);
4550*b7893ccfSSadaf Ebrahimi return;
4551*b7893ccfSSadaf Ebrahimi }
4552*b7893ccfSSadaf Ebrahimi
4553*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures device_features = {};
4554*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
4555*b7893ccfSSadaf Ebrahimi if (VK_TRUE != device_features.sampleRateShading) {
4556*b7893ccfSSadaf Ebrahimi printf("%s Test requires unsupported sampleRateShading feature.\n", kSkipPrefix);
4557*b7893ccfSSadaf Ebrahimi return;
4558*b7893ccfSSadaf Ebrahimi }
4559*b7893ccfSSadaf Ebrahimi
4560*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
4561*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4562*b7893ccfSSadaf Ebrahimi
4563*b7893ccfSSadaf Ebrahimi struct TestCase {
4564*b7893ccfSSadaf Ebrahimi VkSampleCountFlagBits color_samples;
4565*b7893ccfSSadaf Ebrahimi VkSampleCountFlagBits depth_samples;
4566*b7893ccfSSadaf Ebrahimi VkSampleCountFlagBits raster_samples;
4567*b7893ccfSSadaf Ebrahimi VkBool32 depth_test;
4568*b7893ccfSSadaf Ebrahimi VkBool32 sample_shading;
4569*b7893ccfSSadaf Ebrahimi uint32_t table_count;
4570*b7893ccfSSadaf Ebrahimi bool positiveTest;
4571*b7893ccfSSadaf Ebrahimi std::string vuid;
4572*b7893ccfSSadaf Ebrahimi };
4573*b7893ccfSSadaf Ebrahimi
4574*b7893ccfSSadaf Ebrahimi std::vector<TestCase> test_cases = {
4575*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_FALSE, VK_FALSE, 1, true,
4576*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-subpass-00757"},
4577*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_8_BIT, VK_FALSE, VK_FALSE, 4, false,
4578*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineCoverageModulationStateCreateInfoNV-coverageModulationTableEnable-01405"},
4579*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_8_BIT, VK_FALSE, VK_FALSE, 2, true,
4580*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineCoverageModulationStateCreateInfoNV-coverageModulationTableEnable-01405"},
4581*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT, VK_TRUE, VK_FALSE, 1, false,
4582*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-subpass-01411"},
4583*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_8_BIT, VK_SAMPLE_COUNT_8_BIT, VK_TRUE, VK_FALSE, 1, true,
4584*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-subpass-01411"},
4585*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_1_BIT, VK_FALSE, VK_FALSE, 1, false,
4586*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-subpass-01412"},
4587*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_FALSE, VK_FALSE, 1, true,
4588*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-subpass-01412"},
4589*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_FALSE, VK_TRUE, 1, false,
4590*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-01415"},
4591*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_FALSE, VK_FALSE, 1, true,
4592*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-01415"},
4593*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT, VK_FALSE, VK_FALSE, 1, true,
4594*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-subpass-00757"}};
4595*b7893ccfSSadaf Ebrahimi
4596*b7893ccfSSadaf Ebrahimi for (const auto &test_case : test_cases) {
4597*b7893ccfSSadaf Ebrahimi VkAttachmentDescription att[2] = {{}, {}};
4598*b7893ccfSSadaf Ebrahimi att[0].format = VK_FORMAT_R8G8B8A8_UNORM;
4599*b7893ccfSSadaf Ebrahimi att[0].samples = test_case.color_samples;
4600*b7893ccfSSadaf Ebrahimi att[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4601*b7893ccfSSadaf Ebrahimi att[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
4602*b7893ccfSSadaf Ebrahimi
4603*b7893ccfSSadaf Ebrahimi att[1].format = VK_FORMAT_D24_UNORM_S8_UINT;
4604*b7893ccfSSadaf Ebrahimi att[1].samples = test_case.depth_samples;
4605*b7893ccfSSadaf Ebrahimi att[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4606*b7893ccfSSadaf Ebrahimi att[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4607*b7893ccfSSadaf Ebrahimi
4608*b7893ccfSSadaf Ebrahimi VkAttachmentReference cr = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4609*b7893ccfSSadaf Ebrahimi VkAttachmentReference dr = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4610*b7893ccfSSadaf Ebrahimi
4611*b7893ccfSSadaf Ebrahimi VkSubpassDescription sp = {};
4612*b7893ccfSSadaf Ebrahimi sp.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4613*b7893ccfSSadaf Ebrahimi sp.colorAttachmentCount = 1;
4614*b7893ccfSSadaf Ebrahimi sp.pColorAttachments = &cr;
4615*b7893ccfSSadaf Ebrahimi sp.pResolveAttachments = NULL;
4616*b7893ccfSSadaf Ebrahimi sp.pDepthStencilAttachment = &dr;
4617*b7893ccfSSadaf Ebrahimi
4618*b7893ccfSSadaf Ebrahimi VkRenderPassCreateInfo rpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
4619*b7893ccfSSadaf Ebrahimi rpi.attachmentCount = 2;
4620*b7893ccfSSadaf Ebrahimi rpi.pAttachments = att;
4621*b7893ccfSSadaf Ebrahimi rpi.subpassCount = 1;
4622*b7893ccfSSadaf Ebrahimi rpi.pSubpasses = &sp;
4623*b7893ccfSSadaf Ebrahimi
4624*b7893ccfSSadaf Ebrahimi VkRenderPass rp;
4625*b7893ccfSSadaf Ebrahimi
4626*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4627*b7893ccfSSadaf Ebrahimi "VUID-VkSubpassDescription-pDepthStencilAttachment-01418");
4628*b7893ccfSSadaf Ebrahimi VkResult err = vkCreateRenderPass(m_device->device(), &rpi, nullptr, &rp);
4629*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyNotFound();
4630*b7893ccfSSadaf Ebrahimi
4631*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
4632*b7893ccfSSadaf Ebrahimi
4633*b7893ccfSSadaf Ebrahimi VkPipelineDepthStencilStateCreateInfo ds = {VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
4634*b7893ccfSSadaf Ebrahimi VkPipelineCoverageModulationStateCreateInfoNV cmi = {VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV};
4635*b7893ccfSSadaf Ebrahimi
4636*b7893ccfSSadaf Ebrahimi // Create a dummy modulation table that can be used for the positive
4637*b7893ccfSSadaf Ebrahimi // coverageModulationTableCount test.
4638*b7893ccfSSadaf Ebrahimi std::vector<float> cm_table{};
4639*b7893ccfSSadaf Ebrahimi
4640*b7893ccfSSadaf Ebrahimi const auto break_samples = [&cmi, &rp, &ds, &cm_table, &test_case](CreatePipelineHelper &helper) {
4641*b7893ccfSSadaf Ebrahimi cm_table.resize(test_case.raster_samples / test_case.color_samples);
4642*b7893ccfSSadaf Ebrahimi
4643*b7893ccfSSadaf Ebrahimi cmi.flags = 0;
4644*b7893ccfSSadaf Ebrahimi cmi.coverageModulationTableEnable = (test_case.table_count > 1);
4645*b7893ccfSSadaf Ebrahimi cmi.coverageModulationTableCount = test_case.table_count;
4646*b7893ccfSSadaf Ebrahimi cmi.pCoverageModulationTable = cm_table.data();
4647*b7893ccfSSadaf Ebrahimi
4648*b7893ccfSSadaf Ebrahimi ds.depthTestEnable = test_case.depth_test;
4649*b7893ccfSSadaf Ebrahimi
4650*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_.pNext = &cmi;
4651*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_.rasterizationSamples = test_case.raster_samples;
4652*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_.sampleShadingEnable = test_case.sample_shading;
4653*b7893ccfSSadaf Ebrahimi
4654*b7893ccfSSadaf Ebrahimi helper.gp_ci_.renderPass = rp;
4655*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pDepthStencilState = &ds;
4656*b7893ccfSSadaf Ebrahimi };
4657*b7893ccfSSadaf Ebrahimi
4658*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_samples, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuid,
4659*b7893ccfSSadaf Ebrahimi test_case.positiveTest);
4660*b7893ccfSSadaf Ebrahimi
4661*b7893ccfSSadaf Ebrahimi vkDestroyRenderPass(m_device->device(), rp, nullptr);
4662*b7893ccfSSadaf Ebrahimi }
4663*b7893ccfSSadaf Ebrahimi }
4664*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,FramebufferMixedSamples)4665*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, FramebufferMixedSamples) {
4666*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Verify that the expected VUIds are hits when VK_NV_framebuffer_mixed_samples is disabled.");
4667*b7893ccfSSadaf Ebrahimi
4668*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4669*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
4670*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4671*b7893ccfSSadaf Ebrahimi
4672*b7893ccfSSadaf Ebrahimi struct TestCase {
4673*b7893ccfSSadaf Ebrahimi VkSampleCountFlagBits color_samples;
4674*b7893ccfSSadaf Ebrahimi VkSampleCountFlagBits depth_samples;
4675*b7893ccfSSadaf Ebrahimi VkSampleCountFlagBits raster_samples;
4676*b7893ccfSSadaf Ebrahimi bool positiveTest;
4677*b7893ccfSSadaf Ebrahimi };
4678*b7893ccfSSadaf Ebrahimi
4679*b7893ccfSSadaf Ebrahimi std::vector<TestCase> test_cases = {
4680*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT,
4681*b7893ccfSSadaf Ebrahimi false}, // Fails vkCreateRenderPass and vkCreateGraphicsPipeline
4682*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT, false}, // Fails vkCreateGraphicsPipeline
4683*b7893ccfSSadaf Ebrahimi {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, true} // Pass
4684*b7893ccfSSadaf Ebrahimi };
4685*b7893ccfSSadaf Ebrahimi
4686*b7893ccfSSadaf Ebrahimi for (const auto &test_case : test_cases) {
4687*b7893ccfSSadaf Ebrahimi VkAttachmentDescription att[2] = {{}, {}};
4688*b7893ccfSSadaf Ebrahimi att[0].format = VK_FORMAT_R8G8B8A8_UNORM;
4689*b7893ccfSSadaf Ebrahimi att[0].samples = test_case.color_samples;
4690*b7893ccfSSadaf Ebrahimi att[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4691*b7893ccfSSadaf Ebrahimi att[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
4692*b7893ccfSSadaf Ebrahimi
4693*b7893ccfSSadaf Ebrahimi att[1].format = VK_FORMAT_D24_UNORM_S8_UINT;
4694*b7893ccfSSadaf Ebrahimi att[1].samples = test_case.depth_samples;
4695*b7893ccfSSadaf Ebrahimi att[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4696*b7893ccfSSadaf Ebrahimi att[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4697*b7893ccfSSadaf Ebrahimi
4698*b7893ccfSSadaf Ebrahimi VkAttachmentReference cr = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4699*b7893ccfSSadaf Ebrahimi VkAttachmentReference dr = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4700*b7893ccfSSadaf Ebrahimi
4701*b7893ccfSSadaf Ebrahimi VkSubpassDescription sp = {};
4702*b7893ccfSSadaf Ebrahimi sp.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4703*b7893ccfSSadaf Ebrahimi sp.colorAttachmentCount = 1;
4704*b7893ccfSSadaf Ebrahimi sp.pColorAttachments = &cr;
4705*b7893ccfSSadaf Ebrahimi sp.pResolveAttachments = NULL;
4706*b7893ccfSSadaf Ebrahimi sp.pDepthStencilAttachment = &dr;
4707*b7893ccfSSadaf Ebrahimi
4708*b7893ccfSSadaf Ebrahimi VkRenderPassCreateInfo rpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
4709*b7893ccfSSadaf Ebrahimi rpi.attachmentCount = 2;
4710*b7893ccfSSadaf Ebrahimi rpi.pAttachments = att;
4711*b7893ccfSSadaf Ebrahimi rpi.subpassCount = 1;
4712*b7893ccfSSadaf Ebrahimi rpi.pSubpasses = &sp;
4713*b7893ccfSSadaf Ebrahimi
4714*b7893ccfSSadaf Ebrahimi VkRenderPass rp;
4715*b7893ccfSSadaf Ebrahimi
4716*b7893ccfSSadaf Ebrahimi if (test_case.color_samples == test_case.depth_samples) {
4717*b7893ccfSSadaf Ebrahimi m_errorMonitor->ExpectSuccess();
4718*b7893ccfSSadaf Ebrahimi } else {
4719*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4720*b7893ccfSSadaf Ebrahimi "VUID-VkSubpassDescription-pDepthStencilAttachment-01418");
4721*b7893ccfSSadaf Ebrahimi }
4722*b7893ccfSSadaf Ebrahimi
4723*b7893ccfSSadaf Ebrahimi VkResult err = vkCreateRenderPass(m_device->device(), &rpi, nullptr, &rp);
4724*b7893ccfSSadaf Ebrahimi
4725*b7893ccfSSadaf Ebrahimi if (test_case.color_samples == test_case.depth_samples) {
4726*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyNotFound();
4727*b7893ccfSSadaf Ebrahimi } else {
4728*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
4729*b7893ccfSSadaf Ebrahimi continue;
4730*b7893ccfSSadaf Ebrahimi }
4731*b7893ccfSSadaf Ebrahimi
4732*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
4733*b7893ccfSSadaf Ebrahimi
4734*b7893ccfSSadaf Ebrahimi VkPipelineDepthStencilStateCreateInfo ds = {VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
4735*b7893ccfSSadaf Ebrahimi
4736*b7893ccfSSadaf Ebrahimi const auto break_samples = [&rp, &ds, &test_case](CreatePipelineHelper &helper) {
4737*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_.rasterizationSamples = test_case.raster_samples;
4738*b7893ccfSSadaf Ebrahimi
4739*b7893ccfSSadaf Ebrahimi helper.gp_ci_.renderPass = rp;
4740*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pDepthStencilState = &ds;
4741*b7893ccfSSadaf Ebrahimi };
4742*b7893ccfSSadaf Ebrahimi
4743*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_samples, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4744*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-subpass-00757", test_case.positiveTest);
4745*b7893ccfSSadaf Ebrahimi
4746*b7893ccfSSadaf Ebrahimi vkDestroyRenderPass(m_device->device(), rp, nullptr);
4747*b7893ccfSSadaf Ebrahimi }
4748*b7893ccfSSadaf Ebrahimi }
4749*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,FragmentCoverageToColorNV)4750*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, FragmentCoverageToColorNV) {
4751*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Verify VK_NV_fragment_coverage_to_color.");
4752*b7893ccfSSadaf Ebrahimi
4753*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4754*b7893ccfSSadaf Ebrahimi
4755*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME)) {
4756*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME);
4757*b7893ccfSSadaf Ebrahimi } else {
4758*b7893ccfSSadaf Ebrahimi printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME);
4759*b7893ccfSSadaf Ebrahimi return;
4760*b7893ccfSSadaf Ebrahimi }
4761*b7893ccfSSadaf Ebrahimi
4762*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
4763*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4764*b7893ccfSSadaf Ebrahimi
4765*b7893ccfSSadaf Ebrahimi struct TestCase {
4766*b7893ccfSSadaf Ebrahimi VkFormat format;
4767*b7893ccfSSadaf Ebrahimi VkBool32 enabled;
4768*b7893ccfSSadaf Ebrahimi uint32_t location;
4769*b7893ccfSSadaf Ebrahimi bool positive;
4770*b7893ccfSSadaf Ebrahimi };
4771*b7893ccfSSadaf Ebrahimi
4772*b7893ccfSSadaf Ebrahimi const std::array<TestCase, 9> test_cases = {{
4773*b7893ccfSSadaf Ebrahimi {VK_FORMAT_R8G8B8A8_UNORM, VK_FALSE, 0, true},
4774*b7893ccfSSadaf Ebrahimi {VK_FORMAT_R8_UINT, VK_TRUE, 1, true},
4775*b7893ccfSSadaf Ebrahimi {VK_FORMAT_R16_UINT, VK_TRUE, 1, true},
4776*b7893ccfSSadaf Ebrahimi {VK_FORMAT_R16_SINT, VK_TRUE, 1, true},
4777*b7893ccfSSadaf Ebrahimi {VK_FORMAT_R32_UINT, VK_TRUE, 1, true},
4778*b7893ccfSSadaf Ebrahimi {VK_FORMAT_R32_SINT, VK_TRUE, 1, true},
4779*b7893ccfSSadaf Ebrahimi {VK_FORMAT_R32_SINT, VK_TRUE, 2, false},
4780*b7893ccfSSadaf Ebrahimi {VK_FORMAT_R8_SINT, VK_TRUE, 3, false},
4781*b7893ccfSSadaf Ebrahimi {VK_FORMAT_R8G8B8A8_UNORM, VK_TRUE, 1, false},
4782*b7893ccfSSadaf Ebrahimi }};
4783*b7893ccfSSadaf Ebrahimi
4784*b7893ccfSSadaf Ebrahimi for (const auto &test_case : test_cases) {
4785*b7893ccfSSadaf Ebrahimi std::array<VkAttachmentDescription, 2> att = {{{}, {}}};
4786*b7893ccfSSadaf Ebrahimi att[0].format = VK_FORMAT_R8G8B8A8_UNORM;
4787*b7893ccfSSadaf Ebrahimi att[0].samples = VK_SAMPLE_COUNT_1_BIT;
4788*b7893ccfSSadaf Ebrahimi att[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4789*b7893ccfSSadaf Ebrahimi att[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
4790*b7893ccfSSadaf Ebrahimi
4791*b7893ccfSSadaf Ebrahimi att[1].format = VK_FORMAT_R8G8B8A8_UNORM;
4792*b7893ccfSSadaf Ebrahimi att[1].samples = VK_SAMPLE_COUNT_1_BIT;
4793*b7893ccfSSadaf Ebrahimi att[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4794*b7893ccfSSadaf Ebrahimi att[1].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
4795*b7893ccfSSadaf Ebrahimi
4796*b7893ccfSSadaf Ebrahimi if (test_case.location < att.size()) {
4797*b7893ccfSSadaf Ebrahimi att[test_case.location].format = test_case.format;
4798*b7893ccfSSadaf Ebrahimi }
4799*b7893ccfSSadaf Ebrahimi
4800*b7893ccfSSadaf Ebrahimi const std::array<VkAttachmentReference, 3> cr = {{{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4801*b7893ccfSSadaf Ebrahimi {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4802*b7893ccfSSadaf Ebrahimi {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}}};
4803*b7893ccfSSadaf Ebrahimi
4804*b7893ccfSSadaf Ebrahimi VkSubpassDescription sp = {};
4805*b7893ccfSSadaf Ebrahimi sp.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4806*b7893ccfSSadaf Ebrahimi sp.colorAttachmentCount = cr.size();
4807*b7893ccfSSadaf Ebrahimi sp.pColorAttachments = cr.data();
4808*b7893ccfSSadaf Ebrahimi
4809*b7893ccfSSadaf Ebrahimi VkRenderPassCreateInfo rpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
4810*b7893ccfSSadaf Ebrahimi rpi.attachmentCount = att.size();
4811*b7893ccfSSadaf Ebrahimi rpi.pAttachments = att.data();
4812*b7893ccfSSadaf Ebrahimi rpi.subpassCount = 1;
4813*b7893ccfSSadaf Ebrahimi rpi.pSubpasses = &sp;
4814*b7893ccfSSadaf Ebrahimi
4815*b7893ccfSSadaf Ebrahimi const std::array<VkPipelineColorBlendAttachmentState, 3> cba = {{{}, {}, {}}};
4816*b7893ccfSSadaf Ebrahimi
4817*b7893ccfSSadaf Ebrahimi VkPipelineColorBlendStateCreateInfo cbi = {VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO};
4818*b7893ccfSSadaf Ebrahimi cbi.attachmentCount = cba.size();
4819*b7893ccfSSadaf Ebrahimi cbi.pAttachments = cba.data();
4820*b7893ccfSSadaf Ebrahimi
4821*b7893ccfSSadaf Ebrahimi VkRenderPass rp;
4822*b7893ccfSSadaf Ebrahimi VkResult err = vkCreateRenderPass(m_device->device(), &rpi, nullptr, &rp);
4823*b7893ccfSSadaf Ebrahimi ASSERT_VK_SUCCESS(err);
4824*b7893ccfSSadaf Ebrahimi
4825*b7893ccfSSadaf Ebrahimi VkPipelineCoverageToColorStateCreateInfoNV cci = {VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV};
4826*b7893ccfSSadaf Ebrahimi
4827*b7893ccfSSadaf Ebrahimi const auto break_samples = [&cci, &cbi, &rp, &test_case](CreatePipelineHelper &helper) {
4828*b7893ccfSSadaf Ebrahimi cci.coverageToColorEnable = test_case.enabled;
4829*b7893ccfSSadaf Ebrahimi cci.coverageToColorLocation = test_case.location;
4830*b7893ccfSSadaf Ebrahimi
4831*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_.pNext = &cci;
4832*b7893ccfSSadaf Ebrahimi helper.gp_ci_.renderPass = rp;
4833*b7893ccfSSadaf Ebrahimi helper.gp_ci_.pColorBlendState = &cbi;
4834*b7893ccfSSadaf Ebrahimi };
4835*b7893ccfSSadaf Ebrahimi
4836*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_samples, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4837*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineCoverageToColorStateCreateInfoNV-coverageToColorEnable-01404",
4838*b7893ccfSSadaf Ebrahimi test_case.positive);
4839*b7893ccfSSadaf Ebrahimi
4840*b7893ccfSSadaf Ebrahimi vkDestroyRenderPass(m_device->device(), rp, nullptr);
4841*b7893ccfSSadaf Ebrahimi }
4842*b7893ccfSSadaf Ebrahimi }
4843*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,ViewportSwizzleNV)4844*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, ViewportSwizzleNV) {
4845*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Verify VK_NV_viewprot_swizzle.");
4846*b7893ccfSSadaf Ebrahimi
4847*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4848*b7893ccfSSadaf Ebrahimi
4849*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME)) {
4850*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME);
4851*b7893ccfSSadaf Ebrahimi } else {
4852*b7893ccfSSadaf Ebrahimi printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME);
4853*b7893ccfSSadaf Ebrahimi return;
4854*b7893ccfSSadaf Ebrahimi }
4855*b7893ccfSSadaf Ebrahimi
4856*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
4857*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4858*b7893ccfSSadaf Ebrahimi
4859*b7893ccfSSadaf Ebrahimi VkViewportSwizzleNV invalid_swizzles = {
4860*b7893ccfSSadaf Ebrahimi VkViewportCoordinateSwizzleNV(-1),
4861*b7893ccfSSadaf Ebrahimi VkViewportCoordinateSwizzleNV(-1),
4862*b7893ccfSSadaf Ebrahimi VkViewportCoordinateSwizzleNV(-1),
4863*b7893ccfSSadaf Ebrahimi VkViewportCoordinateSwizzleNV(-1),
4864*b7893ccfSSadaf Ebrahimi };
4865*b7893ccfSSadaf Ebrahimi
4866*b7893ccfSSadaf Ebrahimi VkPipelineViewportSwizzleStateCreateInfoNV vp_swizzle_state = {
4867*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV};
4868*b7893ccfSSadaf Ebrahimi vp_swizzle_state.viewportCount = 1;
4869*b7893ccfSSadaf Ebrahimi vp_swizzle_state.pViewportSwizzles = &invalid_swizzles;
4870*b7893ccfSSadaf Ebrahimi
4871*b7893ccfSSadaf Ebrahimi const std::vector<std::string> expected_vuids = {"VUID-VkViewportSwizzleNV-x-parameter", "VUID-VkViewportSwizzleNV-y-parameter",
4872*b7893ccfSSadaf Ebrahimi "VUID-VkViewportSwizzleNV-z-parameter",
4873*b7893ccfSSadaf Ebrahimi "VUID-VkViewportSwizzleNV-w-parameter"};
4874*b7893ccfSSadaf Ebrahimi
4875*b7893ccfSSadaf Ebrahimi auto break_swizzles = [&vp_swizzle_state](CreatePipelineHelper &helper) { helper.vp_state_ci_.pNext = &vp_swizzle_state; };
4876*b7893ccfSSadaf Ebrahimi
4877*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_swizzles, VK_DEBUG_REPORT_ERROR_BIT_EXT, expected_vuids);
4878*b7893ccfSSadaf Ebrahimi
4879*b7893ccfSSadaf Ebrahimi struct TestCase {
4880*b7893ccfSSadaf Ebrahimi VkBool32 rasterizerDiscardEnable;
4881*b7893ccfSSadaf Ebrahimi uint32_t vp_count;
4882*b7893ccfSSadaf Ebrahimi uint32_t swizzel_vp_count;
4883*b7893ccfSSadaf Ebrahimi bool positive;
4884*b7893ccfSSadaf Ebrahimi };
4885*b7893ccfSSadaf Ebrahimi
4886*b7893ccfSSadaf Ebrahimi const std::array<TestCase, 3> test_cases = {{{VK_TRUE, 1, 2, true}, {VK_FALSE, 1, 1, true}, {VK_FALSE, 1, 2, false}}};
4887*b7893ccfSSadaf Ebrahimi
4888*b7893ccfSSadaf Ebrahimi std::array<VkViewportSwizzleNV, 2> swizzles = {
4889*b7893ccfSSadaf Ebrahimi {{VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV,
4890*b7893ccfSSadaf Ebrahimi VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV},
4891*b7893ccfSSadaf Ebrahimi {VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV,
4892*b7893ccfSSadaf Ebrahimi VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV}}};
4893*b7893ccfSSadaf Ebrahimi
4894*b7893ccfSSadaf Ebrahimi for (const auto &test_case : test_cases) {
4895*b7893ccfSSadaf Ebrahimi assert(test_case.vp_count <= swizzles.size());
4896*b7893ccfSSadaf Ebrahimi
4897*b7893ccfSSadaf Ebrahimi vp_swizzle_state.viewportCount = test_case.swizzel_vp_count;
4898*b7893ccfSSadaf Ebrahimi vp_swizzle_state.pViewportSwizzles = swizzles.data();
4899*b7893ccfSSadaf Ebrahimi
4900*b7893ccfSSadaf Ebrahimi auto break_vp_count = [&vp_swizzle_state, &test_case](CreatePipelineHelper &helper) {
4901*b7893ccfSSadaf Ebrahimi helper.rs_state_ci_.rasterizerDiscardEnable = test_case.rasterizerDiscardEnable;
4902*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.viewportCount = test_case.vp_count;
4903*b7893ccfSSadaf Ebrahimi
4904*b7893ccfSSadaf Ebrahimi helper.vp_state_ci_.pNext = &vp_swizzle_state;
4905*b7893ccfSSadaf Ebrahimi };
4906*b7893ccfSSadaf Ebrahimi
4907*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, break_vp_count, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4908*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportSwizzleStateCreateInfoNV-viewportCount-01215",
4909*b7893ccfSSadaf Ebrahimi test_case.positive);
4910*b7893ccfSSadaf Ebrahimi }
4911*b7893ccfSSadaf Ebrahimi }
4912*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CooperativeMatrixNV)4913*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CooperativeMatrixNV) {
4914*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test VK_NV_cooperative_matrix.");
4915*b7893ccfSSadaf Ebrahimi
4916*b7893ccfSSadaf Ebrahimi if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4917*b7893ccfSSadaf Ebrahimi m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4918*b7893ccfSSadaf Ebrahimi } else {
4919*b7893ccfSSadaf Ebrahimi printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
4920*b7893ccfSSadaf Ebrahimi VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4921*b7893ccfSSadaf Ebrahimi return;
4922*b7893ccfSSadaf Ebrahimi }
4923*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4924*b7893ccfSSadaf Ebrahimi std::array<const char *, 2> required_device_extensions = {
4925*b7893ccfSSadaf Ebrahimi {VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME}};
4926*b7893ccfSSadaf Ebrahimi for (auto device_extension : required_device_extensions) {
4927*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
4928*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(device_extension);
4929*b7893ccfSSadaf Ebrahimi } else {
4930*b7893ccfSSadaf Ebrahimi printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
4931*b7893ccfSSadaf Ebrahimi return;
4932*b7893ccfSSadaf Ebrahimi }
4933*b7893ccfSSadaf Ebrahimi }
4934*b7893ccfSSadaf Ebrahimi
4935*b7893ccfSSadaf Ebrahimi if (DeviceIsMockICD() || DeviceSimulation()) {
4936*b7893ccfSSadaf Ebrahimi printf("%s Test not supported by MockICD, skipping tests\n", kSkipPrefix);
4937*b7893ccfSSadaf Ebrahimi return;
4938*b7893ccfSSadaf Ebrahimi }
4939*b7893ccfSSadaf Ebrahimi
4940*b7893ccfSSadaf Ebrahimi PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
4941*b7893ccfSSadaf Ebrahimi (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
4942*b7893ccfSSadaf Ebrahimi ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
4943*b7893ccfSSadaf Ebrahimi
4944*b7893ccfSSadaf Ebrahimi auto float16_features = lvl_init_struct<VkPhysicalDeviceFloat16Int8FeaturesKHR>();
4945*b7893ccfSSadaf Ebrahimi auto cooperative_matrix_features = lvl_init_struct<VkPhysicalDeviceCooperativeMatrixFeaturesNV>(&float16_features);
4946*b7893ccfSSadaf Ebrahimi auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&cooperative_matrix_features);
4947*b7893ccfSSadaf Ebrahimi vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
4948*b7893ccfSSadaf Ebrahimi
4949*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
4950*b7893ccfSSadaf Ebrahimi
4951*b7893ccfSSadaf Ebrahimi std::vector<VkDescriptorSetLayoutBinding> bindings(0);
4952*b7893ccfSSadaf Ebrahimi const VkDescriptorSetLayoutObj dsl(m_device, bindings);
4953*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pl(m_device, {&dsl});
4954*b7893ccfSSadaf Ebrahimi
4955*b7893ccfSSadaf Ebrahimi char const *csSource =
4956*b7893ccfSSadaf Ebrahimi "#version 450\n"
4957*b7893ccfSSadaf Ebrahimi "#extension GL_NV_cooperative_matrix : enable\n"
4958*b7893ccfSSadaf Ebrahimi "#extension GL_KHR_shader_subgroup_basic : enable\n"
4959*b7893ccfSSadaf Ebrahimi "#extension GL_KHR_memory_scope_semantics : enable\n"
4960*b7893ccfSSadaf Ebrahimi "#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable\n"
4961*b7893ccfSSadaf Ebrahimi "layout(local_size_x = 32) in;\n"
4962*b7893ccfSSadaf Ebrahimi "layout(constant_id = 0) const uint C0 = 1;"
4963*b7893ccfSSadaf Ebrahimi "layout(constant_id = 1) const uint C1 = 1;"
4964*b7893ccfSSadaf Ebrahimi "void main() {\n"
4965*b7893ccfSSadaf Ebrahimi // Bad type
4966*b7893ccfSSadaf Ebrahimi " fcoopmatNV<16, gl_ScopeSubgroup, 3, 5> badSize = fcoopmatNV<16, gl_ScopeSubgroup, 3, 5>(float16_t(0.0));\n"
4967*b7893ccfSSadaf Ebrahimi // Not a valid multiply when C0 != C1
4968*b7893ccfSSadaf Ebrahimi " fcoopmatNV<16, gl_ScopeSubgroup, C0, C1> A;\n"
4969*b7893ccfSSadaf Ebrahimi " fcoopmatNV<16, gl_ScopeSubgroup, C0, C1> B;\n"
4970*b7893ccfSSadaf Ebrahimi " fcoopmatNV<16, gl_ScopeSubgroup, C0, C1> C;\n"
4971*b7893ccfSSadaf Ebrahimi " coopMatMulAddNV(A, B, C);\n"
4972*b7893ccfSSadaf Ebrahimi "}\n";
4973*b7893ccfSSadaf Ebrahimi
4974*b7893ccfSSadaf Ebrahimi const uint32_t specData[] = {
4975*b7893ccfSSadaf Ebrahimi 16,
4976*b7893ccfSSadaf Ebrahimi 8,
4977*b7893ccfSSadaf Ebrahimi };
4978*b7893ccfSSadaf Ebrahimi VkSpecializationMapEntry entries[] = {
4979*b7893ccfSSadaf Ebrahimi {0, sizeof(uint32_t) * 0, sizeof(uint32_t)},
4980*b7893ccfSSadaf Ebrahimi {1, sizeof(uint32_t) * 1, sizeof(uint32_t)},
4981*b7893ccfSSadaf Ebrahimi };
4982*b7893ccfSSadaf Ebrahimi
4983*b7893ccfSSadaf Ebrahimi VkSpecializationInfo specInfo = {
4984*b7893ccfSSadaf Ebrahimi 2,
4985*b7893ccfSSadaf Ebrahimi entries,
4986*b7893ccfSSadaf Ebrahimi sizeof(specData),
4987*b7893ccfSSadaf Ebrahimi specData,
4988*b7893ccfSSadaf Ebrahimi };
4989*b7893ccfSSadaf Ebrahimi
4990*b7893ccfSSadaf Ebrahimi CreateComputePipelineHelper pipe(*this);
4991*b7893ccfSSadaf Ebrahimi pipe.InitInfo();
4992*b7893ccfSSadaf Ebrahimi pipe.cs_.reset(new VkShaderObj(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this, "main", false, &specInfo));
4993*b7893ccfSSadaf Ebrahimi pipe.InitState();
4994*b7893ccfSSadaf Ebrahimi pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {});
4995*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-CoreValidation-Shader-CooperativeMatrixType");
4996*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-CoreValidation-Shader-CooperativeMatrixMulAdd");
4997*b7893ccfSSadaf Ebrahimi pipe.CreateComputePipeline();
4998*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
4999*b7893ccfSSadaf Ebrahimi }
5000*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,SubgroupSupportedOperations)5001*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, SubgroupSupportedOperations) {
5002*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test shader validation support for subgroup supportedOperations.");
5003*b7893ccfSSadaf Ebrahimi
5004*b7893ccfSSadaf Ebrahimi SetTargetApiVersion(VK_API_VERSION_1_1);
5005*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5006*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
5007*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5008*b7893ccfSSadaf Ebrahimi
5009*b7893ccfSSadaf Ebrahimi // 1.1 and up only.
5010*b7893ccfSSadaf Ebrahimi if (m_device->props.apiVersion < VK_API_VERSION_1_1) {
5011*b7893ccfSSadaf Ebrahimi printf("%s Vulkan 1.1 not supported, skipping test\n", kSkipPrefix);
5012*b7893ccfSSadaf Ebrahimi return;
5013*b7893ccfSSadaf Ebrahimi }
5014*b7893ccfSSadaf Ebrahimi
5015*b7893ccfSSadaf Ebrahimi if (DeviceIsMockICD() || DeviceSimulation()) {
5016*b7893ccfSSadaf Ebrahimi printf("%s DevSim doesn't support Vulkan 1.1, skipping tests\n", kSkipPrefix);
5017*b7893ccfSSadaf Ebrahimi return;
5018*b7893ccfSSadaf Ebrahimi }
5019*b7893ccfSSadaf Ebrahimi
5020*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceSubgroupProperties subgroup_prop = GetSubgroupProperties(instance(), gpu());
5021*b7893ccfSSadaf Ebrahimi
5022*b7893ccfSSadaf Ebrahimi // CreatePipelineLayout
5023*b7893ccfSSadaf Ebrahimi VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
5024*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
5025*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pNext = NULL;
5026*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.flags = 0;
5027*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.setLayoutCount = 0;
5028*b7893ccfSSadaf Ebrahimi pipeline_layout_ci.pSetLayouts = VK_NULL_HANDLE;
5029*b7893ccfSSadaf Ebrahimi VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
5030*b7893ccfSSadaf Ebrahimi vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
5031*b7893ccfSSadaf Ebrahimi
5032*b7893ccfSSadaf Ebrahimi const std::pair<const char *, VkSubgroupFeatureFlagBits> capabilities[] = {
5033*b7893ccfSSadaf Ebrahimi {"GroupNonUniform", VK_SUBGROUP_FEATURE_BASIC_BIT},
5034*b7893ccfSSadaf Ebrahimi {"GroupNonUniformVote", VK_SUBGROUP_FEATURE_VOTE_BIT},
5035*b7893ccfSSadaf Ebrahimi {"GroupNonUniformArithmetic", VK_SUBGROUP_FEATURE_ARITHMETIC_BIT},
5036*b7893ccfSSadaf Ebrahimi {"GroupNonUniformBallot", VK_SUBGROUP_FEATURE_BALLOT_BIT},
5037*b7893ccfSSadaf Ebrahimi {"GroupNonUniformShuffle", VK_SUBGROUP_FEATURE_SHUFFLE_BIT},
5038*b7893ccfSSadaf Ebrahimi {"GroupNonUniformShuffleRelative", VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT},
5039*b7893ccfSSadaf Ebrahimi {"GroupNonUniformClustered", VK_SUBGROUP_FEATURE_CLUSTERED_BIT},
5040*b7893ccfSSadaf Ebrahimi {"GroupNonUniformQuad", VK_SUBGROUP_FEATURE_QUAD_BIT},
5041*b7893ccfSSadaf Ebrahimi };
5042*b7893ccfSSadaf Ebrahimi
5043*b7893ccfSSadaf Ebrahimi for (auto &capability : capabilities) {
5044*b7893ccfSSadaf Ebrahimi std::string spv_source[3];
5045*b7893ccfSSadaf Ebrahimi
5046*b7893ccfSSadaf Ebrahimi spv_source[0] = "OpCapability " + std::string(capability.first) + "\n" + R"(
5047*b7893ccfSSadaf Ebrahimi OpCapability Shader
5048*b7893ccfSSadaf Ebrahimi OpMemoryModel Logical GLSL450
5049*b7893ccfSSadaf Ebrahimi OpEntryPoint GLCompute %main "main"
5050*b7893ccfSSadaf Ebrahimi OpExecutionMode %main LocalSize 1 1 1
5051*b7893ccfSSadaf Ebrahimi %void = OpTypeVoid
5052*b7893ccfSSadaf Ebrahimi %func = OpTypeFunction %void
5053*b7893ccfSSadaf Ebrahimi %main = OpFunction %void None %func
5054*b7893ccfSSadaf Ebrahimi %40 = OpLabel
5055*b7893ccfSSadaf Ebrahimi OpReturn
5056*b7893ccfSSadaf Ebrahimi OpFunctionEnd
5057*b7893ccfSSadaf Ebrahimi )";
5058*b7893ccfSSadaf Ebrahimi
5059*b7893ccfSSadaf Ebrahimi spv_source[1] = "OpCapability " + std::string(capability.first) + "\n" + R"(
5060*b7893ccfSSadaf Ebrahimi OpCapability Shader
5061*b7893ccfSSadaf Ebrahimi OpMemoryModel Logical GLSL450
5062*b7893ccfSSadaf Ebrahimi OpEntryPoint Vertex %main "main"
5063*b7893ccfSSadaf Ebrahimi %void = OpTypeVoid
5064*b7893ccfSSadaf Ebrahimi %func = OpTypeFunction %void
5065*b7893ccfSSadaf Ebrahimi %main = OpFunction %void None %func
5066*b7893ccfSSadaf Ebrahimi %40 = OpLabel
5067*b7893ccfSSadaf Ebrahimi OpReturn
5068*b7893ccfSSadaf Ebrahimi OpFunctionEnd
5069*b7893ccfSSadaf Ebrahimi )";
5070*b7893ccfSSadaf Ebrahimi
5071*b7893ccfSSadaf Ebrahimi spv_source[2] = "OpCapability " + std::string(capability.first) + "\n" + R"(
5072*b7893ccfSSadaf Ebrahimi OpCapability Shader
5073*b7893ccfSSadaf Ebrahimi OpMemoryModel Logical GLSL450
5074*b7893ccfSSadaf Ebrahimi OpEntryPoint Fragment %main "main"
5075*b7893ccfSSadaf Ebrahimi OpExecutionMode %main OriginUpperLeft
5076*b7893ccfSSadaf Ebrahimi %void = OpTypeVoid
5077*b7893ccfSSadaf Ebrahimi %func = OpTypeFunction %void
5078*b7893ccfSSadaf Ebrahimi %main = OpFunction %void None %func
5079*b7893ccfSSadaf Ebrahimi %40 = OpLabel
5080*b7893ccfSSadaf Ebrahimi OpReturn
5081*b7893ccfSSadaf Ebrahimi OpFunctionEnd
5082*b7893ccfSSadaf Ebrahimi )";
5083*b7893ccfSSadaf Ebrahimi
5084*b7893ccfSSadaf Ebrahimi VkShaderModule shader_module[3];
5085*b7893ccfSSadaf Ebrahimi VkPipelineShaderStageCreateInfo stage[3];
5086*b7893ccfSSadaf Ebrahimi
5087*b7893ccfSSadaf Ebrahimi for (int i = 0; i < 3; ++i) {
5088*b7893ccfSSadaf Ebrahimi // CreateShaderModule
5089*b7893ccfSSadaf Ebrahimi std::vector<unsigned int> spv;
5090*b7893ccfSSadaf Ebrahimi VkShaderModuleCreateInfo module_create_info;
5091*b7893ccfSSadaf Ebrahimi module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
5092*b7893ccfSSadaf Ebrahimi module_create_info.pNext = NULL;
5093*b7893ccfSSadaf Ebrahimi ASMtoSPV(SPV_ENV_VULKAN_1_1, 0, spv_source[i].data(), spv);
5094*b7893ccfSSadaf Ebrahimi module_create_info.pCode = spv.data();
5095*b7893ccfSSadaf Ebrahimi module_create_info.codeSize = spv.size() * sizeof(unsigned int);
5096*b7893ccfSSadaf Ebrahimi module_create_info.flags = 0;
5097*b7893ccfSSadaf Ebrahimi
5098*b7893ccfSSadaf Ebrahimi VkResult result = vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module[i]);
5099*b7893ccfSSadaf Ebrahimi
5100*b7893ccfSSadaf Ebrahimi // NOTE: It appears that for the case of invalid capabilities some drivers (recent AMD) fail at CreateShaderModule time.
5101*b7893ccfSSadaf Ebrahimi // Likely the capability test should be moved up to CSM time, implementing ShaderModuleCreateInfo-pCode-01090
5102*b7893ccfSSadaf Ebrahimi // Note(2) -- yes I truncated the above VUID s.t. the VUID checking tools would not catch it.
5103*b7893ccfSSadaf Ebrahimi if (result != VK_SUCCESS) shader_module[i] = VK_NULL_HANDLE;
5104*b7893ccfSSadaf Ebrahimi
5105*b7893ccfSSadaf Ebrahimi stage[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
5106*b7893ccfSSadaf Ebrahimi stage[i].pNext = nullptr;
5107*b7893ccfSSadaf Ebrahimi stage[i].flags = 0;
5108*b7893ccfSSadaf Ebrahimi // stage[i].stage initialized later;
5109*b7893ccfSSadaf Ebrahimi stage[i].module = shader_module[i];
5110*b7893ccfSSadaf Ebrahimi stage[i].pName = "main";
5111*b7893ccfSSadaf Ebrahimi stage[i].pSpecializationInfo = nullptr;
5112*b7893ccfSSadaf Ebrahimi }
5113*b7893ccfSSadaf Ebrahimi
5114*b7893ccfSSadaf Ebrahimi // CreateComputePipelines
5115*b7893ccfSSadaf Ebrahimi VkComputePipelineCreateInfo pipeline_info = {};
5116*b7893ccfSSadaf Ebrahimi pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
5117*b7893ccfSSadaf Ebrahimi pipeline_info.pNext = nullptr;
5118*b7893ccfSSadaf Ebrahimi pipeline_info.flags = 0;
5119*b7893ccfSSadaf Ebrahimi pipeline_info.layout = pipeline_layout;
5120*b7893ccfSSadaf Ebrahimi pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
5121*b7893ccfSSadaf Ebrahimi pipeline_info.basePipelineIndex = -1;
5122*b7893ccfSSadaf Ebrahimi pipeline_info.stage = stage[0];
5123*b7893ccfSSadaf Ebrahimi pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
5124*b7893ccfSSadaf Ebrahimi
5125*b7893ccfSSadaf Ebrahimi if (pipeline_info.stage.module != VK_NULL_HANDLE) {
5126*b7893ccfSSadaf Ebrahimi if (!(subgroup_prop.supportedOperations & capability.second)) {
5127*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
5128*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceSubgroupProperties::supportedOperations");
5129*b7893ccfSSadaf Ebrahimi }
5130*b7893ccfSSadaf Ebrahimi if (!(subgroup_prop.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT)) {
5131*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
5132*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceSubgroupProperties::supportedStages");
5133*b7893ccfSSadaf Ebrahimi }
5134*b7893ccfSSadaf Ebrahimi
5135*b7893ccfSSadaf Ebrahimi VkPipeline cs_pipeline;
5136*b7893ccfSSadaf Ebrahimi vkCreateComputePipelines(device(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &cs_pipeline);
5137*b7893ccfSSadaf Ebrahimi vkDestroyPipeline(device(), cs_pipeline, nullptr);
5138*b7893ccfSSadaf Ebrahimi
5139*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5140*b7893ccfSSadaf Ebrahimi }
5141*b7893ccfSSadaf Ebrahimi
5142*b7893ccfSSadaf Ebrahimi if ((stage[1].module != VK_NULL_HANDLE) && (stage[2].module != VK_NULL_HANDLE)) {
5143*b7893ccfSSadaf Ebrahimi stage[1].stage = VK_SHADER_STAGE_VERTEX_BIT;
5144*b7893ccfSSadaf Ebrahimi stage[2].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
5145*b7893ccfSSadaf Ebrahimi
5146*b7893ccfSSadaf Ebrahimi VkPipelineObj pipe(m_device);
5147*b7893ccfSSadaf Ebrahimi pipe.AddShader(stage[1]);
5148*b7893ccfSSadaf Ebrahimi pipe.AddShader(stage[2]);
5149*b7893ccfSSadaf Ebrahimi pipe.AddDefaultColorAttachment();
5150*b7893ccfSSadaf Ebrahimi
5151*b7893ccfSSadaf Ebrahimi if (!(subgroup_prop.supportedOperations & capability.second)) {
5152*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
5153*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceSubgroupProperties::supportedOperations");
5154*b7893ccfSSadaf Ebrahimi }
5155*b7893ccfSSadaf Ebrahimi if (!(subgroup_prop.supportedStages & VK_SHADER_STAGE_VERTEX_BIT)) {
5156*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
5157*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceSubgroupProperties::supportedStages");
5158*b7893ccfSSadaf Ebrahimi }
5159*b7893ccfSSadaf Ebrahimi if (!(subgroup_prop.supportedOperations & capability.second)) {
5160*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
5161*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceSubgroupProperties::supportedOperations");
5162*b7893ccfSSadaf Ebrahimi }
5163*b7893ccfSSadaf Ebrahimi if (!(subgroup_prop.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT)) {
5164*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
5165*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceSubgroupProperties::supportedStages");
5166*b7893ccfSSadaf Ebrahimi }
5167*b7893ccfSSadaf Ebrahimi pipe.CreateVKPipeline(pipeline_layout, renderPass());
5168*b7893ccfSSadaf Ebrahimi
5169*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5170*b7893ccfSSadaf Ebrahimi }
5171*b7893ccfSSadaf Ebrahimi
5172*b7893ccfSSadaf Ebrahimi vkDestroyShaderModule(device(), shader_module[0], nullptr);
5173*b7893ccfSSadaf Ebrahimi vkDestroyShaderModule(device(), shader_module[1], nullptr);
5174*b7893ccfSSadaf Ebrahimi vkDestroyShaderModule(device(), shader_module[2], nullptr);
5175*b7893ccfSSadaf Ebrahimi }
5176*b7893ccfSSadaf Ebrahimi
5177*b7893ccfSSadaf Ebrahimi vkDestroyPipelineLayout(device(), pipeline_layout, nullptr);
5178*b7893ccfSSadaf Ebrahimi }
5179*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,SubgroupRequired)5180*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, SubgroupRequired) {
5181*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test that the minimum required functionality for subgroups is present.");
5182*b7893ccfSSadaf Ebrahimi
5183*b7893ccfSSadaf Ebrahimi SetTargetApiVersion(VK_API_VERSION_1_1);
5184*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5185*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
5186*b7893ccfSSadaf Ebrahimi
5187*b7893ccfSSadaf Ebrahimi // 1.1 and up only.
5188*b7893ccfSSadaf Ebrahimi if (m_device->props.apiVersion < VK_API_VERSION_1_1) {
5189*b7893ccfSSadaf Ebrahimi printf("%s Vulkan 1.1 not supported, skipping test\n", kSkipPrefix);
5190*b7893ccfSSadaf Ebrahimi return;
5191*b7893ccfSSadaf Ebrahimi }
5192*b7893ccfSSadaf Ebrahimi
5193*b7893ccfSSadaf Ebrahimi if (DeviceIsMockICD() || DeviceSimulation()) {
5194*b7893ccfSSadaf Ebrahimi printf("%s DevSim doesn't support Vulkan 1.1, skipping tests\n", kSkipPrefix);
5195*b7893ccfSSadaf Ebrahimi return;
5196*b7893ccfSSadaf Ebrahimi }
5197*b7893ccfSSadaf Ebrahimi
5198*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceSubgroupProperties subgroup_prop = GetSubgroupProperties(instance(), gpu());
5199*b7893ccfSSadaf Ebrahimi
5200*b7893ccfSSadaf Ebrahimi auto queue_family_properties = m_device->phy().queue_properties();
5201*b7893ccfSSadaf Ebrahimi
5202*b7893ccfSSadaf Ebrahimi bool foundGraphics = false;
5203*b7893ccfSSadaf Ebrahimi bool foundCompute = false;
5204*b7893ccfSSadaf Ebrahimi
5205*b7893ccfSSadaf Ebrahimi for (auto queue_family : queue_family_properties) {
5206*b7893ccfSSadaf Ebrahimi if (queue_family.queueFlags & VK_QUEUE_COMPUTE_BIT) {
5207*b7893ccfSSadaf Ebrahimi foundCompute = true;
5208*b7893ccfSSadaf Ebrahimi break;
5209*b7893ccfSSadaf Ebrahimi }
5210*b7893ccfSSadaf Ebrahimi
5211*b7893ccfSSadaf Ebrahimi if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
5212*b7893ccfSSadaf Ebrahimi foundGraphics = true;
5213*b7893ccfSSadaf Ebrahimi }
5214*b7893ccfSSadaf Ebrahimi }
5215*b7893ccfSSadaf Ebrahimi
5216*b7893ccfSSadaf Ebrahimi if (!(foundGraphics || foundCompute)) return;
5217*b7893ccfSSadaf Ebrahimi
5218*b7893ccfSSadaf Ebrahimi ASSERT_GE(subgroup_prop.subgroupSize, 1u);
5219*b7893ccfSSadaf Ebrahimi
5220*b7893ccfSSadaf Ebrahimi if (foundCompute) {
5221*b7893ccfSSadaf Ebrahimi ASSERT_TRUE(subgroup_prop.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT);
5222*b7893ccfSSadaf Ebrahimi }
5223*b7893ccfSSadaf Ebrahimi
5224*b7893ccfSSadaf Ebrahimi ASSERT_TRUE(subgroup_prop.supportedOperations & VK_SUBGROUP_FEATURE_BASIC_BIT);
5225*b7893ccfSSadaf Ebrahimi }
5226*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,GraphicsPipelineStageCreationFeedbackCount)5227*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, GraphicsPipelineStageCreationFeedbackCount) {
5228*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test graphics pipeline feedback stage count check.");
5229*b7893ccfSSadaf Ebrahimi
5230*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5231*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME)) {
5232*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME);
5233*b7893ccfSSadaf Ebrahimi } else {
5234*b7893ccfSSadaf Ebrahimi printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME);
5235*b7893ccfSSadaf Ebrahimi return;
5236*b7893ccfSSadaf Ebrahimi }
5237*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
5238*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5239*b7893ccfSSadaf Ebrahimi
5240*b7893ccfSSadaf Ebrahimi auto feedback_info = lvl_init_struct<VkPipelineCreationFeedbackCreateInfoEXT>();
5241*b7893ccfSSadaf Ebrahimi VkPipelineCreationFeedbackEXT feedbacks[3] = {};
5242*b7893ccfSSadaf Ebrahimi
5243*b7893ccfSSadaf Ebrahimi feedback_info.pPipelineCreationFeedback = &feedbacks[0];
5244*b7893ccfSSadaf Ebrahimi feedback_info.pipelineStageCreationFeedbackCount = 2;
5245*b7893ccfSSadaf Ebrahimi feedback_info.pPipelineStageCreationFeedbacks = &feedbacks[1];
5246*b7893ccfSSadaf Ebrahimi
5247*b7893ccfSSadaf Ebrahimi auto set_feedback = [&feedback_info](CreatePipelineHelper &helper) { helper.gp_ci_.pNext = &feedback_info; };
5248*b7893ccfSSadaf Ebrahimi
5249*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_feedback, VK_DEBUG_REPORT_ERROR_BIT_EXT,
5250*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineCreationFeedbackCreateInfoEXT-pipelineStageCreationFeedbackCount-02668",
5251*b7893ccfSSadaf Ebrahimi true);
5252*b7893ccfSSadaf Ebrahimi
5253*b7893ccfSSadaf Ebrahimi feedback_info.pipelineStageCreationFeedbackCount = 1;
5254*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_feedback, VK_DEBUG_REPORT_ERROR_BIT_EXT,
5255*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineCreationFeedbackCreateInfoEXT-pipelineStageCreationFeedbackCount-02668",
5256*b7893ccfSSadaf Ebrahimi false);
5257*b7893ccfSSadaf Ebrahimi }
5258*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,ComputePipelineStageCreationFeedbackCount)5259*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, ComputePipelineStageCreationFeedbackCount) {
5260*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test compute pipeline feedback stage count check.");
5261*b7893ccfSSadaf Ebrahimi
5262*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5263*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME)) {
5264*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME);
5265*b7893ccfSSadaf Ebrahimi } else {
5266*b7893ccfSSadaf Ebrahimi printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME);
5267*b7893ccfSSadaf Ebrahimi return;
5268*b7893ccfSSadaf Ebrahimi }
5269*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
5270*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5271*b7893ccfSSadaf Ebrahimi
5272*b7893ccfSSadaf Ebrahimi VkPipelineCreationFeedbackCreateInfoEXT feedback_info = {};
5273*b7893ccfSSadaf Ebrahimi VkPipelineCreationFeedbackEXT feedbacks[3] = {};
5274*b7893ccfSSadaf Ebrahimi feedback_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT;
5275*b7893ccfSSadaf Ebrahimi feedback_info.pPipelineCreationFeedback = &feedbacks[0];
5276*b7893ccfSSadaf Ebrahimi feedback_info.pipelineStageCreationFeedbackCount = 1;
5277*b7893ccfSSadaf Ebrahimi feedback_info.pPipelineStageCreationFeedbacks = &feedbacks[1];
5278*b7893ccfSSadaf Ebrahimi
5279*b7893ccfSSadaf Ebrahimi const auto set_info = [&](CreateComputePipelineHelper &helper) { helper.cp_ci_.pNext = &feedback_info; };
5280*b7893ccfSSadaf Ebrahimi
5281*b7893ccfSSadaf Ebrahimi CreateComputePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT, "", true);
5282*b7893ccfSSadaf Ebrahimi
5283*b7893ccfSSadaf Ebrahimi feedback_info.pipelineStageCreationFeedbackCount = 2;
5284*b7893ccfSSadaf Ebrahimi CreateComputePipelineHelper::OneshotTest(
5285*b7893ccfSSadaf Ebrahimi *this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT,
5286*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineCreationFeedbackCreateInfoEXT-pipelineStageCreationFeedbackCount-02669");
5287*b7893ccfSSadaf Ebrahimi }
5288*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,NVRayTracingPipelineStageCreationFeedbackCount)5289*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, NVRayTracingPipelineStageCreationFeedbackCount) {
5290*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test NV ray tracing pipeline feedback stage count check.");
5291*b7893ccfSSadaf Ebrahimi
5292*b7893ccfSSadaf Ebrahimi if (!CreateNVRayTracingPipelineHelper::InitInstanceExtensions(*this, m_instance_extension_names)) {
5293*b7893ccfSSadaf Ebrahimi return;
5294*b7893ccfSSadaf Ebrahimi }
5295*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5296*b7893ccfSSadaf Ebrahimi
5297*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME)) {
5298*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME);
5299*b7893ccfSSadaf Ebrahimi } else {
5300*b7893ccfSSadaf Ebrahimi printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME);
5301*b7893ccfSSadaf Ebrahimi return;
5302*b7893ccfSSadaf Ebrahimi }
5303*b7893ccfSSadaf Ebrahimi
5304*b7893ccfSSadaf Ebrahimi if (!CreateNVRayTracingPipelineHelper::InitDeviceExtensions(*this, m_device_extension_names)) {
5305*b7893ccfSSadaf Ebrahimi return;
5306*b7893ccfSSadaf Ebrahimi }
5307*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState());
5308*b7893ccfSSadaf Ebrahimi
5309*b7893ccfSSadaf Ebrahimi auto feedback_info = lvl_init_struct<VkPipelineCreationFeedbackCreateInfoEXT>();
5310*b7893ccfSSadaf Ebrahimi VkPipelineCreationFeedbackEXT feedbacks[4] = {};
5311*b7893ccfSSadaf Ebrahimi
5312*b7893ccfSSadaf Ebrahimi feedback_info.pPipelineCreationFeedback = &feedbacks[0];
5313*b7893ccfSSadaf Ebrahimi feedback_info.pipelineStageCreationFeedbackCount = 2;
5314*b7893ccfSSadaf Ebrahimi feedback_info.pPipelineStageCreationFeedbacks = &feedbacks[1];
5315*b7893ccfSSadaf Ebrahimi
5316*b7893ccfSSadaf Ebrahimi auto set_feedback = [&feedback_info](CreateNVRayTracingPipelineHelper &helper) { helper.rp_ci_.pNext = &feedback_info; };
5317*b7893ccfSSadaf Ebrahimi
5318*b7893ccfSSadaf Ebrahimi feedback_info.pipelineStageCreationFeedbackCount = 3;
5319*b7893ccfSSadaf Ebrahimi CreateNVRayTracingPipelineHelper::OneshotPositiveTest(*this, set_feedback);
5320*b7893ccfSSadaf Ebrahimi
5321*b7893ccfSSadaf Ebrahimi feedback_info.pipelineStageCreationFeedbackCount = 2;
5322*b7893ccfSSadaf Ebrahimi CreateNVRayTracingPipelineHelper::OneshotTest(
5323*b7893ccfSSadaf Ebrahimi *this, set_feedback, "VUID-VkPipelineCreationFeedbackCreateInfoEXT-pipelineStageCreationFeedbackCount-02670");
5324*b7893ccfSSadaf Ebrahimi }
5325*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckShaderImageFootprintEnabled)5326*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckShaderImageFootprintEnabled) {
5327*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Create a pipeline requiring the shader image footprint feature which has not enabled on the device.");
5328*b7893ccfSSadaf Ebrahimi
5329*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
5330*b7893ccfSSadaf Ebrahimi
5331*b7893ccfSSadaf Ebrahimi if (!DeviceExtensionSupported(gpu(), nullptr, VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME)) {
5332*b7893ccfSSadaf Ebrahimi printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME);
5333*b7893ccfSSadaf Ebrahimi return;
5334*b7893ccfSSadaf Ebrahimi }
5335*b7893ccfSSadaf Ebrahimi
5336*b7893ccfSSadaf Ebrahimi std::vector<const char *> device_extension_names;
5337*b7893ccfSSadaf Ebrahimi auto features = m_device->phy().features();
5338*b7893ccfSSadaf Ebrahimi
5339*b7893ccfSSadaf Ebrahimi // Disable the image footprint feature.
5340*b7893ccfSSadaf Ebrahimi auto image_footprint_features = lvl_init_struct<VkPhysicalDeviceShaderImageFootprintFeaturesNV>();
5341*b7893ccfSSadaf Ebrahimi image_footprint_features.imageFootprint = VK_FALSE;
5342*b7893ccfSSadaf Ebrahimi
5343*b7893ccfSSadaf Ebrahimi VkDeviceObj test_device(0, gpu(), device_extension_names, &features, &image_footprint_features);
5344*b7893ccfSSadaf Ebrahimi
5345*b7893ccfSSadaf Ebrahimi char const *fsSource =
5346*b7893ccfSSadaf Ebrahimi "#version 450\n"
5347*b7893ccfSSadaf Ebrahimi "#extension GL_NV_shader_texture_footprint : require\n"
5348*b7893ccfSSadaf Ebrahimi "layout(set=0, binding=0) uniform sampler2D s;\n"
5349*b7893ccfSSadaf Ebrahimi "layout(location=0) out vec4 color;\n"
5350*b7893ccfSSadaf Ebrahimi "void main(){\n"
5351*b7893ccfSSadaf Ebrahimi " gl_TextureFootprint2DNV footprint;\n"
5352*b7893ccfSSadaf Ebrahimi " if (textureFootprintNV(s, vec2(1.0), 5, false, footprint)) {\n"
5353*b7893ccfSSadaf Ebrahimi " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
5354*b7893ccfSSadaf Ebrahimi " } else {\n"
5355*b7893ccfSSadaf Ebrahimi " color = vec4(vec2(footprint.anchor), vec2(footprint.offset));\n"
5356*b7893ccfSSadaf Ebrahimi " }\n"
5357*b7893ccfSSadaf Ebrahimi "}\n";
5358*b7893ccfSSadaf Ebrahimi
5359*b7893ccfSSadaf Ebrahimi VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5360*b7893ccfSSadaf Ebrahimi VkShaderObj fs(&test_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5361*b7893ccfSSadaf Ebrahimi
5362*b7893ccfSSadaf Ebrahimi VkRenderpassObj render_pass(&test_device);
5363*b7893ccfSSadaf Ebrahimi
5364*b7893ccfSSadaf Ebrahimi VkPipelineObj pipe(&test_device);
5365*b7893ccfSSadaf Ebrahimi pipe.AddDefaultColorAttachment();
5366*b7893ccfSSadaf Ebrahimi pipe.AddShader(&vs);
5367*b7893ccfSSadaf Ebrahimi pipe.AddShader(&fs);
5368*b7893ccfSSadaf Ebrahimi
5369*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
5370*b7893ccfSSadaf Ebrahimi const VkDescriptorSetLayoutObj ds_layout(&test_device, {binding});
5371*b7893ccfSSadaf Ebrahimi ASSERT_TRUE(ds_layout.initialized());
5372*b7893ccfSSadaf Ebrahimi
5373*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pipeline_layout(&test_device, {&ds_layout});
5374*b7893ccfSSadaf Ebrahimi
5375*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
5376*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5377*b7893ccfSSadaf Ebrahimi "Shader requires VkPhysicalDeviceShaderImageFootprintFeaturesNV::imageFootprint but is not enabled on the device");
5378*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
5379*b7893ccfSSadaf Ebrahimi "Shader requires extension VkPhysicalDeviceShaderImageFootprintFeaturesNV::imageFootprint "
5380*b7893ccfSSadaf Ebrahimi "but is not enabled on the device");
5381*b7893ccfSSadaf Ebrahimi pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
5382*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5383*b7893ccfSSadaf Ebrahimi }
5384*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckFragmentShaderBarycentricEnabled)5385*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckFragmentShaderBarycentricEnabled) {
5386*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Create a pipeline requiring the fragment shader barycentric feature which has not enabled on the device.");
5387*b7893ccfSSadaf Ebrahimi
5388*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
5389*b7893ccfSSadaf Ebrahimi
5390*b7893ccfSSadaf Ebrahimi std::vector<const char *> device_extension_names;
5391*b7893ccfSSadaf Ebrahimi auto features = m_device->phy().features();
5392*b7893ccfSSadaf Ebrahimi
5393*b7893ccfSSadaf Ebrahimi // Disable the fragment shader barycentric feature.
5394*b7893ccfSSadaf Ebrahimi auto fragment_shader_barycentric_features = lvl_init_struct<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>();
5395*b7893ccfSSadaf Ebrahimi fragment_shader_barycentric_features.fragmentShaderBarycentric = VK_FALSE;
5396*b7893ccfSSadaf Ebrahimi
5397*b7893ccfSSadaf Ebrahimi VkDeviceObj test_device(0, gpu(), device_extension_names, &features, &fragment_shader_barycentric_features);
5398*b7893ccfSSadaf Ebrahimi
5399*b7893ccfSSadaf Ebrahimi char const *fsSource =
5400*b7893ccfSSadaf Ebrahimi "#version 450\n"
5401*b7893ccfSSadaf Ebrahimi "#extension GL_NV_fragment_shader_barycentric : require\n"
5402*b7893ccfSSadaf Ebrahimi "layout(location=0) out float value;\n"
5403*b7893ccfSSadaf Ebrahimi "void main(){\n"
5404*b7893ccfSSadaf Ebrahimi " value = gl_BaryCoordNV.x;\n"
5405*b7893ccfSSadaf Ebrahimi "}\n";
5406*b7893ccfSSadaf Ebrahimi
5407*b7893ccfSSadaf Ebrahimi VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5408*b7893ccfSSadaf Ebrahimi VkShaderObj fs(&test_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5409*b7893ccfSSadaf Ebrahimi
5410*b7893ccfSSadaf Ebrahimi VkRenderpassObj render_pass(&test_device);
5411*b7893ccfSSadaf Ebrahimi
5412*b7893ccfSSadaf Ebrahimi VkPipelineObj pipe(&test_device);
5413*b7893ccfSSadaf Ebrahimi pipe.AddDefaultColorAttachment();
5414*b7893ccfSSadaf Ebrahimi pipe.AddShader(&vs);
5415*b7893ccfSSadaf Ebrahimi pipe.AddShader(&fs);
5416*b7893ccfSSadaf Ebrahimi
5417*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pipeline_layout(&test_device);
5418*b7893ccfSSadaf Ebrahimi
5419*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
5420*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5421*b7893ccfSSadaf Ebrahimi "Shader requires VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV::fragmentShaderBarycentric but is not enabled on the "
5422*b7893ccfSSadaf Ebrahimi "device");
5423*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
5424*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5425*b7893ccfSSadaf Ebrahimi "Shader requires extension VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV::fragmentShaderBarycentric but is not "
5426*b7893ccfSSadaf Ebrahimi "enabled on the device");
5427*b7893ccfSSadaf Ebrahimi pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
5428*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5429*b7893ccfSSadaf Ebrahimi }
5430*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckComputeShaderDerivativesEnabled)5431*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckComputeShaderDerivativesEnabled) {
5432*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Create a pipeline requiring the compute shader derivatives feature which has not enabled on the device.");
5433*b7893ccfSSadaf Ebrahimi
5434*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
5435*b7893ccfSSadaf Ebrahimi
5436*b7893ccfSSadaf Ebrahimi std::vector<const char *> device_extension_names;
5437*b7893ccfSSadaf Ebrahimi auto features = m_device->phy().features();
5438*b7893ccfSSadaf Ebrahimi
5439*b7893ccfSSadaf Ebrahimi // Disable the compute shader derivatives features.
5440*b7893ccfSSadaf Ebrahimi auto compute_shader_derivatives_features = lvl_init_struct<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>();
5441*b7893ccfSSadaf Ebrahimi compute_shader_derivatives_features.computeDerivativeGroupLinear = VK_FALSE;
5442*b7893ccfSSadaf Ebrahimi compute_shader_derivatives_features.computeDerivativeGroupQuads = VK_FALSE;
5443*b7893ccfSSadaf Ebrahimi
5444*b7893ccfSSadaf Ebrahimi VkDeviceObj test_device(0, gpu(), device_extension_names, &features, &compute_shader_derivatives_features);
5445*b7893ccfSSadaf Ebrahimi
5446*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
5447*b7893ccfSSadaf Ebrahimi const VkDescriptorSetLayoutObj dsl(&test_device, {binding});
5448*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pl(&test_device, {&dsl});
5449*b7893ccfSSadaf Ebrahimi
5450*b7893ccfSSadaf Ebrahimi char const *csSource =
5451*b7893ccfSSadaf Ebrahimi "#version 450\n"
5452*b7893ccfSSadaf Ebrahimi "#extension GL_NV_compute_shader_derivatives : require\n"
5453*b7893ccfSSadaf Ebrahimi "\n"
5454*b7893ccfSSadaf Ebrahimi "layout(local_size_x=2, local_size_y=4) in;\n"
5455*b7893ccfSSadaf Ebrahimi "layout(derivative_group_quadsNV) in;\n"
5456*b7893ccfSSadaf Ebrahimi "\n"
5457*b7893ccfSSadaf Ebrahimi "layout(set=0, binding=0) buffer InputOutputBuffer {\n"
5458*b7893ccfSSadaf Ebrahimi " float values[];\n"
5459*b7893ccfSSadaf Ebrahimi "};\n"
5460*b7893ccfSSadaf Ebrahimi "\n"
5461*b7893ccfSSadaf Ebrahimi "void main(){\n"
5462*b7893ccfSSadaf Ebrahimi " values[gl_LocalInvocationIndex] = dFdx(values[gl_LocalInvocationIndex]);"
5463*b7893ccfSSadaf Ebrahimi "}\n";
5464*b7893ccfSSadaf Ebrahimi
5465*b7893ccfSSadaf Ebrahimi VkShaderObj cs(&test_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
5466*b7893ccfSSadaf Ebrahimi
5467*b7893ccfSSadaf Ebrahimi VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
5468*b7893ccfSSadaf Ebrahimi nullptr,
5469*b7893ccfSSadaf Ebrahimi 0,
5470*b7893ccfSSadaf Ebrahimi {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
5471*b7893ccfSSadaf Ebrahimi VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
5472*b7893ccfSSadaf Ebrahimi pl.handle(),
5473*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE,
5474*b7893ccfSSadaf Ebrahimi -1};
5475*b7893ccfSSadaf Ebrahimi
5476*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
5477*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5478*b7893ccfSSadaf Ebrahimi "Shader requires VkPhysicalDeviceComputeShaderDerivativesFeaturesNV::computeDerivativeGroupQuads but is not enabled on the "
5479*b7893ccfSSadaf Ebrahimi "device");
5480*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
5481*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5482*b7893ccfSSadaf Ebrahimi "Shader requires extension VkPhysicalDeviceComputeShaderDerivativesFeaturesNV::computeDerivativeGroupQuads but is not "
5483*b7893ccfSSadaf Ebrahimi "enabled on the device");
5484*b7893ccfSSadaf Ebrahimi
5485*b7893ccfSSadaf Ebrahimi VkPipeline pipe = VK_NULL_HANDLE;
5486*b7893ccfSSadaf Ebrahimi vkCreateComputePipelines(test_device.device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
5487*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5488*b7893ccfSSadaf Ebrahimi vkDestroyPipeline(test_device.device(), pipe, nullptr);
5489*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5490*b7893ccfSSadaf Ebrahimi }
5491*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckFragmentShaderInterlockEnabled)5492*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckFragmentShaderInterlockEnabled) {
5493*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Create a pipeline requiring the fragment shader interlock feature which has not enabled on the device.");
5494*b7893ccfSSadaf Ebrahimi
5495*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
5496*b7893ccfSSadaf Ebrahimi
5497*b7893ccfSSadaf Ebrahimi std::vector<const char *> device_extension_names;
5498*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME)) {
5499*b7893ccfSSadaf Ebrahimi // Note: we intentionally do not add the required extension to the device extension list.
5500*b7893ccfSSadaf Ebrahimi // in order to create the error below
5501*b7893ccfSSadaf Ebrahimi } else {
5502*b7893ccfSSadaf Ebrahimi // We skip this test if the extension is not supported by the driver as in some cases this will cause
5503*b7893ccfSSadaf Ebrahimi // the vkCreateShaderModule to fail without generating an error message
5504*b7893ccfSSadaf Ebrahimi printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME);
5505*b7893ccfSSadaf Ebrahimi return;
5506*b7893ccfSSadaf Ebrahimi }
5507*b7893ccfSSadaf Ebrahimi
5508*b7893ccfSSadaf Ebrahimi auto features = m_device->phy().features();
5509*b7893ccfSSadaf Ebrahimi
5510*b7893ccfSSadaf Ebrahimi // Disable the fragment shader interlock feature.
5511*b7893ccfSSadaf Ebrahimi auto fragment_shader_interlock_features = lvl_init_struct<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>();
5512*b7893ccfSSadaf Ebrahimi fragment_shader_interlock_features.fragmentShaderSampleInterlock = VK_FALSE;
5513*b7893ccfSSadaf Ebrahimi fragment_shader_interlock_features.fragmentShaderPixelInterlock = VK_FALSE;
5514*b7893ccfSSadaf Ebrahimi fragment_shader_interlock_features.fragmentShaderShadingRateInterlock = VK_FALSE;
5515*b7893ccfSSadaf Ebrahimi
5516*b7893ccfSSadaf Ebrahimi VkDeviceObj test_device(0, gpu(), device_extension_names, &features, &fragment_shader_interlock_features);
5517*b7893ccfSSadaf Ebrahimi
5518*b7893ccfSSadaf Ebrahimi char const *fsSource =
5519*b7893ccfSSadaf Ebrahimi "#version 450\n"
5520*b7893ccfSSadaf Ebrahimi "#extension GL_ARB_fragment_shader_interlock : require\n"
5521*b7893ccfSSadaf Ebrahimi "layout(sample_interlock_ordered) in;\n"
5522*b7893ccfSSadaf Ebrahimi "void main(){\n"
5523*b7893ccfSSadaf Ebrahimi "}\n";
5524*b7893ccfSSadaf Ebrahimi
5525*b7893ccfSSadaf Ebrahimi VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5526*b7893ccfSSadaf Ebrahimi VkShaderObj fs(&test_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5527*b7893ccfSSadaf Ebrahimi
5528*b7893ccfSSadaf Ebrahimi VkRenderpassObj render_pass(&test_device);
5529*b7893ccfSSadaf Ebrahimi
5530*b7893ccfSSadaf Ebrahimi VkPipelineObj pipe(&test_device);
5531*b7893ccfSSadaf Ebrahimi pipe.AddDefaultColorAttachment();
5532*b7893ccfSSadaf Ebrahimi pipe.AddShader(&vs);
5533*b7893ccfSSadaf Ebrahimi pipe.AddShader(&fs);
5534*b7893ccfSSadaf Ebrahimi
5535*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pipeline_layout(&test_device);
5536*b7893ccfSSadaf Ebrahimi
5537*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
5538*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5539*b7893ccfSSadaf Ebrahimi "Shader requires VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT::fragmentShaderSampleInterlock but is not enabled on "
5540*b7893ccfSSadaf Ebrahimi "the device");
5541*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
5542*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5543*b7893ccfSSadaf Ebrahimi "Shader requires extension VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT::fragmentShaderSampleInterlock but is not "
5544*b7893ccfSSadaf Ebrahimi "enabled on the device");
5545*b7893ccfSSadaf Ebrahimi pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
5546*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5547*b7893ccfSSadaf Ebrahimi }
5548*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckDemoteToHelperInvocation)5549*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckDemoteToHelperInvocation) {
5550*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Create a pipeline requiring the demote to helper invocation feature which has not enabled on the device.");
5551*b7893ccfSSadaf Ebrahimi
5552*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(Init());
5553*b7893ccfSSadaf Ebrahimi
5554*b7893ccfSSadaf Ebrahimi std::vector<const char *> device_extension_names;
5555*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME)) {
5556*b7893ccfSSadaf Ebrahimi // Note: we intentionally do not add the required extension to the device extension list.
5557*b7893ccfSSadaf Ebrahimi // in order to create the error below
5558*b7893ccfSSadaf Ebrahimi } else {
5559*b7893ccfSSadaf Ebrahimi // We skip this test if the extension is not supported by the driver as in some cases this will cause
5560*b7893ccfSSadaf Ebrahimi // the vkCreateShaderModule to fail without generating an error message
5561*b7893ccfSSadaf Ebrahimi printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME);
5562*b7893ccfSSadaf Ebrahimi return;
5563*b7893ccfSSadaf Ebrahimi }
5564*b7893ccfSSadaf Ebrahimi
5565*b7893ccfSSadaf Ebrahimi auto features = m_device->phy().features();
5566*b7893ccfSSadaf Ebrahimi
5567*b7893ccfSSadaf Ebrahimi // Disable the demote to helper invocation feature.
5568*b7893ccfSSadaf Ebrahimi auto demote_features = lvl_init_struct<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>();
5569*b7893ccfSSadaf Ebrahimi demote_features.shaderDemoteToHelperInvocation = VK_FALSE;
5570*b7893ccfSSadaf Ebrahimi
5571*b7893ccfSSadaf Ebrahimi VkDeviceObj test_device(0, gpu(), device_extension_names, &features, &demote_features);
5572*b7893ccfSSadaf Ebrahimi
5573*b7893ccfSSadaf Ebrahimi char const *fsSource =
5574*b7893ccfSSadaf Ebrahimi "#version 450\n"
5575*b7893ccfSSadaf Ebrahimi "#extension GL_EXT_demote_to_helper_invocation : require\n"
5576*b7893ccfSSadaf Ebrahimi "void main(){\n"
5577*b7893ccfSSadaf Ebrahimi " demote;\n"
5578*b7893ccfSSadaf Ebrahimi "}\n";
5579*b7893ccfSSadaf Ebrahimi
5580*b7893ccfSSadaf Ebrahimi VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5581*b7893ccfSSadaf Ebrahimi VkShaderObj fs(&test_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5582*b7893ccfSSadaf Ebrahimi
5583*b7893ccfSSadaf Ebrahimi VkRenderpassObj render_pass(&test_device);
5584*b7893ccfSSadaf Ebrahimi
5585*b7893ccfSSadaf Ebrahimi VkPipelineObj pipe(&test_device);
5586*b7893ccfSSadaf Ebrahimi pipe.AddDefaultColorAttachment();
5587*b7893ccfSSadaf Ebrahimi pipe.AddShader(&vs);
5588*b7893ccfSSadaf Ebrahimi pipe.AddShader(&fs);
5589*b7893ccfSSadaf Ebrahimi
5590*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutObj pipeline_layout(&test_device);
5591*b7893ccfSSadaf Ebrahimi
5592*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
5593*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5594*b7893ccfSSadaf Ebrahimi "Shader requires VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT::shaderDemoteToHelperInvocation but is not "
5595*b7893ccfSSadaf Ebrahimi "enabled on "
5596*b7893ccfSSadaf Ebrahimi "the device");
5597*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(
5598*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5599*b7893ccfSSadaf Ebrahimi "Shader requires extension VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT::shaderDemoteToHelperInvocation but "
5600*b7893ccfSSadaf Ebrahimi "is not "
5601*b7893ccfSSadaf Ebrahimi "enabled on the device");
5602*b7893ccfSSadaf Ebrahimi pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
5603*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5604*b7893ccfSSadaf Ebrahimi }
5605*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,CreatePipelineCheckLineRasterization)5606*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, CreatePipelineCheckLineRasterization) {
5607*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Test VK_EXT_line_rasterization state against feature enables.");
5608*b7893ccfSSadaf Ebrahimi
5609*b7893ccfSSadaf Ebrahimi if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5610*b7893ccfSSadaf Ebrahimi m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5611*b7893ccfSSadaf Ebrahimi } else {
5612*b7893ccfSSadaf Ebrahimi printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5613*b7893ccfSSadaf Ebrahimi VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5614*b7893ccfSSadaf Ebrahimi return;
5615*b7893ccfSSadaf Ebrahimi }
5616*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5617*b7893ccfSSadaf Ebrahimi std::array<const char *, 1> required_device_extensions = {{VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME}};
5618*b7893ccfSSadaf Ebrahimi for (auto device_extension : required_device_extensions) {
5619*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
5620*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(device_extension);
5621*b7893ccfSSadaf Ebrahimi } else {
5622*b7893ccfSSadaf Ebrahimi printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
5623*b7893ccfSSadaf Ebrahimi return;
5624*b7893ccfSSadaf Ebrahimi }
5625*b7893ccfSSadaf Ebrahimi }
5626*b7893ccfSSadaf Ebrahimi
5627*b7893ccfSSadaf Ebrahimi PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
5628*b7893ccfSSadaf Ebrahimi (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
5629*b7893ccfSSadaf Ebrahimi ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5630*b7893ccfSSadaf Ebrahimi
5631*b7893ccfSSadaf Ebrahimi auto line_rasterization_features = lvl_init_struct<VkPhysicalDeviceLineRasterizationFeaturesEXT>();
5632*b7893ccfSSadaf Ebrahimi auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&line_rasterization_features);
5633*b7893ccfSSadaf Ebrahimi vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
5634*b7893ccfSSadaf Ebrahimi
5635*b7893ccfSSadaf Ebrahimi line_rasterization_features.rectangularLines = VK_FALSE;
5636*b7893ccfSSadaf Ebrahimi line_rasterization_features.bresenhamLines = VK_FALSE;
5637*b7893ccfSSadaf Ebrahimi line_rasterization_features.smoothLines = VK_FALSE;
5638*b7893ccfSSadaf Ebrahimi line_rasterization_features.stippledRectangularLines = VK_FALSE;
5639*b7893ccfSSadaf Ebrahimi line_rasterization_features.stippledBresenhamLines = VK_FALSE;
5640*b7893ccfSSadaf Ebrahimi line_rasterization_features.stippledSmoothLines = VK_FALSE;
5641*b7893ccfSSadaf Ebrahimi
5642*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
5643*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5644*b7893ccfSSadaf Ebrahimi
5645*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
5646*b7893ccfSSadaf Ebrahimi *this,
5647*b7893ccfSSadaf Ebrahimi [&](CreatePipelineHelper &helper) {
5648*b7893ccfSSadaf Ebrahimi helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
5649*b7893ccfSSadaf Ebrahimi helper.pipe_ms_state_ci_.alphaToCoverageEnable = VK_TRUE;
5650*b7893ccfSSadaf Ebrahimi },
5651*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5652*b7893ccfSSadaf Ebrahimi std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-lineRasterizationMode-02766",
5653*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02769"});
5654*b7893ccfSSadaf Ebrahimi
5655*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
5656*b7893ccfSSadaf Ebrahimi *this,
5657*b7893ccfSSadaf Ebrahimi [&](CreatePipelineHelper &helper) {
5658*b7893ccfSSadaf Ebrahimi helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
5659*b7893ccfSSadaf Ebrahimi helper.line_state_ci_.stippledLineEnable = VK_TRUE;
5660*b7893ccfSSadaf Ebrahimi },
5661*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5662*b7893ccfSSadaf Ebrahimi std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767",
5663*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02769",
5664*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02772"});
5665*b7893ccfSSadaf Ebrahimi
5666*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
5667*b7893ccfSSadaf Ebrahimi *this,
5668*b7893ccfSSadaf Ebrahimi [&](CreatePipelineHelper &helper) {
5669*b7893ccfSSadaf Ebrahimi helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
5670*b7893ccfSSadaf Ebrahimi helper.line_state_ci_.stippledLineEnable = VK_TRUE;
5671*b7893ccfSSadaf Ebrahimi },
5672*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5673*b7893ccfSSadaf Ebrahimi std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767",
5674*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02768",
5675*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02771"});
5676*b7893ccfSSadaf Ebrahimi
5677*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
5678*b7893ccfSSadaf Ebrahimi *this,
5679*b7893ccfSSadaf Ebrahimi [&](CreatePipelineHelper &helper) {
5680*b7893ccfSSadaf Ebrahimi helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
5681*b7893ccfSSadaf Ebrahimi helper.line_state_ci_.stippledLineEnable = VK_TRUE;
5682*b7893ccfSSadaf Ebrahimi },
5683*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5684*b7893ccfSSadaf Ebrahimi std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767",
5685*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02770",
5686*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02773"});
5687*b7893ccfSSadaf Ebrahimi
5688*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(
5689*b7893ccfSSadaf Ebrahimi *this,
5690*b7893ccfSSadaf Ebrahimi [&](CreatePipelineHelper &helper) {
5691*b7893ccfSSadaf Ebrahimi helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
5692*b7893ccfSSadaf Ebrahimi helper.line_state_ci_.stippledLineEnable = VK_TRUE;
5693*b7893ccfSSadaf Ebrahimi },
5694*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_ERROR_BIT_EXT,
5695*b7893ccfSSadaf Ebrahimi std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767",
5696*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02774"});
5697*b7893ccfSSadaf Ebrahimi
5698*b7893ccfSSadaf Ebrahimi PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT =
5699*b7893ccfSSadaf Ebrahimi (PFN_vkCmdSetLineStippleEXT)vkGetDeviceProcAddr(m_device->device(), "vkCmdSetLineStippleEXT");
5700*b7893ccfSSadaf Ebrahimi ASSERT_TRUE(vkCmdSetLineStippleEXT != nullptr);
5701*b7893ccfSSadaf Ebrahimi
5702*b7893ccfSSadaf Ebrahimi m_commandBuffer->begin();
5703*b7893ccfSSadaf Ebrahimi m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetLineStippleEXT-lineStippleFactor-02776");
5704*b7893ccfSSadaf Ebrahimi vkCmdSetLineStippleEXT(m_commandBuffer->handle(), 0, 0);
5705*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5706*b7893ccfSSadaf Ebrahimi vkCmdSetLineStippleEXT(m_commandBuffer->handle(), 1, 1);
5707*b7893ccfSSadaf Ebrahimi m_errorMonitor->VerifyFound();
5708*b7893ccfSSadaf Ebrahimi }
5709*b7893ccfSSadaf Ebrahimi
TEST_F(VkLayerTest,FillRectangleNV)5710*b7893ccfSSadaf Ebrahimi TEST_F(VkLayerTest, FillRectangleNV) {
5711*b7893ccfSSadaf Ebrahimi TEST_DESCRIPTION("Verify VK_NV_fill_rectangle");
5712*b7893ccfSSadaf Ebrahimi
5713*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5714*b7893ccfSSadaf Ebrahimi
5715*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceFeatures device_features = {};
5716*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
5717*b7893ccfSSadaf Ebrahimi
5718*b7893ccfSSadaf Ebrahimi // Disable non-solid fill modes to make sure that the usage of VK_POLYGON_MODE_LINE and
5719*b7893ccfSSadaf Ebrahimi // VK_POLYGON_MODE_POINT will cause an error when the VK_NV_fill_rectangle extension is enabled.
5720*b7893ccfSSadaf Ebrahimi device_features.fillModeNonSolid = VK_FALSE;
5721*b7893ccfSSadaf Ebrahimi
5722*b7893ccfSSadaf Ebrahimi if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_FILL_RECTANGLE_EXTENSION_NAME)) {
5723*b7893ccfSSadaf Ebrahimi m_device_extension_names.push_back(VK_NV_FILL_RECTANGLE_EXTENSION_NAME);
5724*b7893ccfSSadaf Ebrahimi } else {
5725*b7893ccfSSadaf Ebrahimi printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_FILL_RECTANGLE_EXTENSION_NAME);
5726*b7893ccfSSadaf Ebrahimi return;
5727*b7893ccfSSadaf Ebrahimi }
5728*b7893ccfSSadaf Ebrahimi
5729*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
5730*b7893ccfSSadaf Ebrahimi ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5731*b7893ccfSSadaf Ebrahimi
5732*b7893ccfSSadaf Ebrahimi VkPolygonMode polygon_mode = VK_POLYGON_MODE_LINE;
5733*b7893ccfSSadaf Ebrahimi
5734*b7893ccfSSadaf Ebrahimi auto set_polygon_mode = [&polygon_mode](CreatePipelineHelper &helper) { helper.rs_state_ci_.polygonMode = polygon_mode; };
5735*b7893ccfSSadaf Ebrahimi
5736*b7893ccfSSadaf Ebrahimi // Set unsupported polygon mode VK_POLYGON_MODE_LINE
5737*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_polygon_mode, VK_DEBUG_REPORT_ERROR_BIT_EXT,
5738*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01507", false);
5739*b7893ccfSSadaf Ebrahimi
5740*b7893ccfSSadaf Ebrahimi // Set unsupported polygon mode VK_POLYGON_MODE_POINT
5741*b7893ccfSSadaf Ebrahimi polygon_mode = VK_POLYGON_MODE_POINT;
5742*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_polygon_mode, VK_DEBUG_REPORT_ERROR_BIT_EXT,
5743*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01507", false);
5744*b7893ccfSSadaf Ebrahimi
5745*b7893ccfSSadaf Ebrahimi // Set supported polygon mode VK_POLYGON_MODE_FILL
5746*b7893ccfSSadaf Ebrahimi polygon_mode = VK_POLYGON_MODE_FILL;
5747*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_polygon_mode, VK_DEBUG_REPORT_ERROR_BIT_EXT,
5748*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01507", true);
5749*b7893ccfSSadaf Ebrahimi
5750*b7893ccfSSadaf Ebrahimi // Set supported polygon mode VK_POLYGON_MODE_FILL_RECTANGLE_NV
5751*b7893ccfSSadaf Ebrahimi polygon_mode = VK_POLYGON_MODE_FILL_RECTANGLE_NV;
5752*b7893ccfSSadaf Ebrahimi CreatePipelineHelper::OneshotTest(*this, set_polygon_mode, VK_DEBUG_REPORT_ERROR_BIT_EXT,
5753*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01507", true);
5754*b7893ccfSSadaf Ebrahimi }
5755