blob: fcea3d3473e3f0efac4fdb73de045f203f0cc243 [file] [log] [blame]
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001#include <vulkan.h>
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002#include "vk_debug_report_lunarg.h"
Tony Barbour300a6082015-04-07 13:44:53 -06003#include "gtest-1.7.0/include/gtest/gtest.h"
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06004#include "vkrenderframework.h"
Mark Lobodzinski159ffe02015-05-14 14:30:48 -05005#include "layers_config.h"
Tony Barbour300a6082015-04-07 13:44:53 -06006
Mark Lobodzinski3780e142015-05-14 15:08:13 -05007#define GLM_FORCE_RADIANS
8#include "glm/glm.hpp"
9#include <glm/gtc/matrix_transform.hpp>
10
Tobin Ehlis0788f522015-05-26 16:11:58 -060011#define MEM_TRACKER_TESTS 1
12#define OBJ_TRACKER_TESTS 1
13#define DRAW_STATE_TESTS 1
14#define THREADING_TESTS 1
Chris Forbes9f7ff632015-05-25 11:13:08 +120015#define SHADER_CHECKER_TESTS 1
Tobin Ehlis0788f522015-05-26 16:11:58 -060016
Mark Lobodzinski3780e142015-05-14 15:08:13 -050017//--------------------------------------------------------------------------------------
18// Mesh and VertexFormat Data
19//--------------------------------------------------------------------------------------
20struct Vertex
21{
22 float posX, posY, posZ, posW; // Position data
23 float r, g, b, a; // Color
24};
25
26#define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
27
28typedef enum _BsoFailSelect {
29 BsoFailNone = 0x00000000,
30 BsoFailRaster = 0x00000001,
31 BsoFailViewport = 0x00000002,
32 BsoFailColorBlend = 0x00000004,
33 BsoFailDepthStencil = 0x00000008,
34} BsoFailSelect;
35
36struct vktriangle_vs_uniform {
37 // Must start with MVP
38 float mvp[4][4];
39 float position[3][4];
40 float color[3][4];
41};
42
Mark Lobodzinski75a97e62015-06-02 09:41:30 -050043static const char bindStateVertShaderText[] =
Mark Lobodzinski3780e142015-05-14 15:08:13 -050044 "#version 130\n"
45 "vec2 vertices[3];\n"
46 "void main() {\n"
47 " vertices[0] = vec2(-1.0, -1.0);\n"
48 " vertices[1] = vec2( 1.0, -1.0);\n"
49 " vertices[2] = vec2( 0.0, 1.0);\n"
50 " gl_Position = vec4(vertices[gl_VertexID % 3], 0.0, 1.0);\n"
51 "}\n";
52
Mark Lobodzinski75a97e62015-06-02 09:41:30 -050053static const char bindStateFragShaderText[] =
Cody Northrop8a3bb132015-06-16 17:32:04 -060054 "#version 140\n"
55 "#extension GL_ARB_separate_shader_objects: require\n"
56 "#extension GL_ARB_shading_language_420pack: require\n"
57 "\n"
58 "layout(location = 0) out vec4 uFragColor;\n"
59 "void main(){\n"
60 " uFragColor = vec4(0,1,0,1);\n"
61 "}\n";
Mark Lobodzinski3780e142015-05-14 15:08:13 -050062
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060063static void myDbgFunc(
64 VkFlags msgFlags,
65 VkObjectType objType,
66 VkObject srcObject,
67 size_t location,
68 int32_t msgCode,
69 const char* pLayerPrefix,
70 const char* pMsg,
71 void* pUserData);
Tony Barbour300a6082015-04-07 13:44:53 -060072
73class ErrorMonitor {
74public:
Tony Barbour15524c32015-04-29 17:34:29 -060075 ErrorMonitor()
Tony Barbour300a6082015-04-07 13:44:53 -060076 {
Mike Stroyanaccf7692015-05-12 16:00:45 -060077 pthread_mutexattr_t attr;
78 pthread_mutexattr_init(&attr);
79 pthread_mutex_init(&m_mutex, &attr);
80 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060081 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Mike Stroyanaccf7692015-05-12 16:00:45 -060082 m_bailout = NULL;
83 pthread_mutex_unlock(&m_mutex);
Tony Barbour300a6082015-04-07 13:44:53 -060084 }
85 void ClearState()
86 {
Mike Stroyanaccf7692015-05-12 16:00:45 -060087 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060088 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Tony Barbour300a6082015-04-07 13:44:53 -060089 m_msgString.clear();
Mike Stroyanaccf7692015-05-12 16:00:45 -060090 pthread_mutex_unlock(&m_mutex);
Tony Barbour300a6082015-04-07 13:44:53 -060091 }
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060092 VkFlags GetState(std::string *msgString)
Tony Barbour300a6082015-04-07 13:44:53 -060093 {
Mike Stroyanaccf7692015-05-12 16:00:45 -060094 pthread_mutex_lock(&m_mutex);
Tony Barbour300a6082015-04-07 13:44:53 -060095 *msgString = m_msgString;
Mike Stroyanaccf7692015-05-12 16:00:45 -060096 pthread_mutex_unlock(&m_mutex);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060097 return m_msgFlags;
Tony Barbour300a6082015-04-07 13:44:53 -060098 }
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060099 void SetState(VkFlags msgFlags, const char *msgString)
Tony Barbour300a6082015-04-07 13:44:53 -0600100 {
Mike Stroyanaccf7692015-05-12 16:00:45 -0600101 pthread_mutex_lock(&m_mutex);
102 if (m_bailout != NULL) {
103 *m_bailout = true;
104 }
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600105 m_msgFlags = msgFlags;
Tony Barbour0b4d9562015-04-09 10:48:04 -0600106 m_msgString.reserve(strlen(msgString));
107 m_msgString = msgString;
Mike Stroyanaccf7692015-05-12 16:00:45 -0600108 pthread_mutex_unlock(&m_mutex);
109 }
110 void SetBailout(bool *bailout)
111 {
112 m_bailout = bailout;
Tony Barbour300a6082015-04-07 13:44:53 -0600113 }
114
115private:
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600116 VkFlags m_msgFlags;
Mike Stroyanaccf7692015-05-12 16:00:45 -0600117 std::string m_msgString;
118 pthread_mutex_t m_mutex;
119 bool* m_bailout;
Tony Barbour300a6082015-04-07 13:44:53 -0600120};
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500121
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600122static void myDbgFunc(
123 VkFlags msgFlags,
124 VkObjectType objType,
125 VkObject srcObject,
126 size_t location,
127 int32_t msgCode,
128 const char* pLayerPrefix,
129 const char* pMsg,
130 void* pUserData)
Tony Barbour300a6082015-04-07 13:44:53 -0600131{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600132 if (msgFlags & (VK_DBG_REPORT_WARN_BIT | VK_DBG_REPORT_ERROR_BIT)) {
Tony Barbour0b4d9562015-04-09 10:48:04 -0600133 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600134 errMonitor->SetState(msgFlags, pMsg);
Tony Barbour0b4d9562015-04-09 10:48:04 -0600135 }
Tony Barbour300a6082015-04-07 13:44:53 -0600136}
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500137
Tony Barbour6918cd52015-04-09 12:58:51 -0600138class VkLayerTest : public VkRenderFramework
Tony Barbour300a6082015-04-07 13:44:53 -0600139{
140public:
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600141 VkResult BeginCommandBuffer(VkCommandBufferObj &cmdBuffer);
142 VkResult EndCommandBuffer(VkCommandBufferObj &cmdBuffer);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500143 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
144 void GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask);
Tony Barbour300a6082015-04-07 13:44:53 -0600145
146protected:
Tony Barbour6918cd52015-04-09 12:58:51 -0600147 VkMemoryRefManager m_memoryRefManager;
148 ErrorMonitor *m_errorMonitor;
Tony Barbour300a6082015-04-07 13:44:53 -0600149
150 virtual void SetUp() {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600151 std::vector<const char *> instance_extension_names;
152 std::vector<const char *> device_extension_names;
Tony Barbour3fdff9e2015-04-23 12:55:36 -0600153
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600154 instance_extension_names.push_back(DEBUG_REPORT_EXTENSION_NAME);
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -0600155 instance_extension_names.push_back("MemTracker");
Courtney Goeltzenleuchterc56b3682015-06-01 14:51:01 -0600156 instance_extension_names.push_back("DrawState");
157// instance_extension_names.push_back("ObjectTracker");
Courtney Goeltzenleuchter6a26d3e2015-06-01 14:13:33 -0600158// instance_extension_names.push_back("Threading");
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -0600159
160 device_extension_names.push_back("MemTracker");
Courtney Goeltzenleuchterc56b3682015-06-01 14:51:01 -0600161// device_extension_names.push_back("ObjectTracker");
162// device_extension_names.push_back("Threading");
Tony Barbour300a6082015-04-07 13:44:53 -0600163
Mark Lobodzinski159ffe02015-05-14 14:30:48 -0500164 // Force layer output level to be >= WARNING so that we catch those messages but ignore others
165 setLayerOptionEnum("MemTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
166 setLayerOptionEnum("ObjectTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
167 setLayerOptionEnum("ThreadingReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Tobin Ehlis49eb23d2015-05-22 12:38:55 -0600168 setLayerOptionEnum("DrawStateReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Chris Forbes3bdefef2015-05-25 11:13:00 +1200169 setLayerOptionEnum("ShaderCheckerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Mark Lobodzinski159ffe02015-05-14 14:30:48 -0500170
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600171 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour300a6082015-04-07 13:44:53 -0600172 this->app_info.pNext = NULL;
173 this->app_info.pAppName = "layer_tests";
174 this->app_info.appVersion = 1;
175 this->app_info.pEngineName = "unittest";
176 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600177 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour300a6082015-04-07 13:44:53 -0600178
Tony Barbour15524c32015-04-29 17:34:29 -0600179 m_errorMonitor = new ErrorMonitor;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600180 InitFramework(instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
Tony Barbour300a6082015-04-07 13:44:53 -0600181 }
182
183 virtual void TearDown() {
184 // Clean up resources before we reset
Tony Barbour300a6082015-04-07 13:44:53 -0600185 ShutdownFramework();
Tony Barbour0b4d9562015-04-09 10:48:04 -0600186 delete m_errorMonitor;
Tony Barbour300a6082015-04-07 13:44:53 -0600187 }
188};
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500189
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600190VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour300a6082015-04-07 13:44:53 -0600191{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600192 VkResult result;
Tony Barbour300a6082015-04-07 13:44:53 -0600193
194 result = cmdBuffer.BeginCommandBuffer();
195
196 /*
197 * For render test all drawing happens in a single render pass
198 * on a single command buffer.
199 */
Chris Forbes76a5eeb2015-06-16 14:05:59 +1200200 if (VK_SUCCESS == result && renderPass()) {
Tony Barbour300a6082015-04-07 13:44:53 -0600201 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
202 }
203
204 return result;
205}
206
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600207VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour300a6082015-04-07 13:44:53 -0600208{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600209 VkResult result;
Tony Barbour300a6082015-04-07 13:44:53 -0600210
Chris Forbes76a5eeb2015-06-16 14:05:59 +1200211 if (renderPass()) {
212 cmdBuffer.EndRenderPass(renderPass());
213 }
Tony Barbour300a6082015-04-07 13:44:53 -0600214
215 result = cmdBuffer.EndCommandBuffer();
216
217 return result;
218}
219
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500220void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
221{
222 // Create identity matrix
223 int i;
224 struct vktriangle_vs_uniform data;
225
226 glm::mat4 Projection = glm::mat4(1.0f);
227 glm::mat4 View = glm::mat4(1.0f);
228 glm::mat4 Model = glm::mat4(1.0f);
229 glm::mat4 MVP = Projection * View * Model;
230 const int matrixSize = sizeof(MVP);
231 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
232
233 memcpy(&data.mvp, &MVP[0][0], matrixSize);
234
235 static const Vertex tri_data[] =
236 {
237 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
238 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
239 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
240 };
241
242 for (i=0; i<3; i++) {
243 data.position[i][0] = tri_data[i].posX;
244 data.position[i][1] = tri_data[i].posY;
245 data.position[i][2] = tri_data[i].posZ;
246 data.position[i][3] = tri_data[i].posW;
247 data.color[i][0] = tri_data[i].r;
248 data.color[i][1] = tri_data[i].g;
249 data.color[i][2] = tri_data[i].b;
250 data.color[i][3] = tri_data[i].a;
251 }
252
253 ASSERT_NO_FATAL_FAILURE(InitState());
254 ASSERT_NO_FATAL_FAILURE(InitViewport());
255
256 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
257
258 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
259 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
260
261 VkPipelineObj pipelineobj(m_device);
262 pipelineobj.AddShader(&vs);
263 pipelineobj.AddShader(&ps);
264
265 VkDescriptorSetObj descriptorSet(m_device);
266 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
267
268 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
269 VkCommandBufferObj cmdBuffer(m_device);
270 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
271
272 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
273
274 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
275
276 // render triangle
277 cmdBuffer.Draw(0, 3, 0, 1);
278
279 // finalize recording of the command buffer
280 EndCommandBuffer(cmdBuffer);
281
282 cmdBuffer.QueueCommandBuffer();
283}
284
285void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
286{
287 if (m_depthStencil->Initialized()) {
288 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
289 } else {
290 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
291 }
292
293 cmdBuffer->PrepareAttachments();
294 if ((failMask & BsoFailRaster) != BsoFailRaster) {
295 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
296 }
297 if ((failMask & BsoFailViewport) != BsoFailViewport) {
298 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
299 }
300 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
301 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
302 }
303 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
304 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
305 }
306 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
307 pipelineobj.CreateVKPipeline(descriptorSet);
308 cmdBuffer->BindPipeline(pipelineobj);
309 cmdBuffer->BindDescriptorSet(descriptorSet);
310}
311
312// ********************************************************************************************************************
313// ********************************************************************************************************************
314// ********************************************************************************************************************
315// ********************************************************************************************************************
Tobin Ehlis0788f522015-05-26 16:11:58 -0600316#if MEM_TRACKER_TESTS
Mark Lobodzinskiccb2b042015-05-19 10:28:29 -0500317TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
318{
319 vk_testing::Fence testFence;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600320 VkFlags msgFlags;
Mark Lobodzinskiccb2b042015-05-19 10:28:29 -0500321 std::string msgString;
322
323 VkFenceCreateInfo fenceInfo = {};
324 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
325 fenceInfo.pNext = NULL;
326 fenceInfo.flags = 0;
327
328 ASSERT_NO_FATAL_FAILURE(InitState());
329 ASSERT_NO_FATAL_FAILURE(InitViewport());
330 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
331
332 VkCommandBufferObj cmdBuffer(m_device);
333 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
334
335 BeginCommandBuffer(cmdBuffer);
336 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
337 EndCommandBuffer(cmdBuffer);
338
339 testFence.init(*m_device, fenceInfo);
340
341 // Bypass framework since it does the waits automatically
342 VkResult err = VK_SUCCESS;
343 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
344 ASSERT_VK_SUCCESS( err );
345
346 m_errorMonitor->ClearState();
347 // Introduce failure by calling begin again before checking fence
348 vkResetCommandBuffer(cmdBuffer.obj());
349
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600350 msgFlags = m_errorMonitor->GetState(&msgString);
351 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
Mark Lobodzinskiccb2b042015-05-19 10:28:29 -0500352 if (!strstr(msgString.c_str(),"Resetting CB")) {
353 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
354 }
355}
356
357TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
358{
359 vk_testing::Fence testFence;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600360 VkFlags msgFlags;
Mark Lobodzinskiccb2b042015-05-19 10:28:29 -0500361 std::string msgString;
362
363 VkFenceCreateInfo fenceInfo = {};
364 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
365 fenceInfo.pNext = NULL;
366 fenceInfo.flags = 0;
367
368 ASSERT_NO_FATAL_FAILURE(InitState());
369 ASSERT_NO_FATAL_FAILURE(InitViewport());
370 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
371
372 VkCommandBufferObj cmdBuffer(m_device);
373 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
374
375 BeginCommandBuffer(cmdBuffer);
376 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
377 EndCommandBuffer(cmdBuffer);
378
379 testFence.init(*m_device, fenceInfo);
380
381 // Bypass framework since it does the waits automatically
382 VkResult err = VK_SUCCESS;
383 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
384 ASSERT_VK_SUCCESS( err );
385
386 m_errorMonitor->ClearState();
387 // Introduce failure by calling begin again before checking fence
388 BeginCommandBuffer(cmdBuffer);
389
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600390 msgFlags = m_errorMonitor->GetState(&msgString);
391 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
Mark Lobodzinskiccb2b042015-05-19 10:28:29 -0500392 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
393 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
394 }
395}
396
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500397TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
398{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600399 VkFlags msgFlags;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500400 std::string msgString;
401 VkResult err;
402
403 ASSERT_NO_FATAL_FAILURE(InitState());
404 m_errorMonitor->ClearState();
405
406 // Create an image, allocate memory, free it, and then try to bind it
407 VkImage image;
Mark Lobodzinski23065352015-05-29 09:32:35 -0500408 VkDeviceMemory mem;
409 VkMemoryRequirements mem_reqs;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500410
411 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
412 const int32_t tex_width = 32;
413 const int32_t tex_height = 32;
414 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500415
416 const VkImageCreateInfo image_create_info = {
417 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
418 .pNext = NULL,
419 .imageType = VK_IMAGE_TYPE_2D,
420 .format = tex_format,
421 .extent = { tex_width, tex_height, 1 },
422 .mipLevels = 1,
423 .arraySize = 1,
424 .samples = 1,
425 .tiling = VK_IMAGE_TILING_LINEAR,
426 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
427 .flags = 0,
428 };
429 VkMemoryAllocInfo mem_alloc = {
430 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
431 .pNext = NULL,
432 .allocationSize = 0,
433 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
434 .memProps = 0,
435 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
436 };
437
438 err = vkCreateImage(m_device->device(), &image_create_info, &image);
439 ASSERT_VK_SUCCESS(err);
440
441 err = vkGetObjectInfo(m_device->device(),
442 VK_OBJECT_TYPE_IMAGE,
443 image,
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500444 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
445 &mem_reqs_size,
Mark Lobodzinski23065352015-05-29 09:32:35 -0500446 &mem_reqs);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500447 ASSERT_VK_SUCCESS(err);
448
Mark Lobodzinski23065352015-05-29 09:32:35 -0500449 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500450
451 // allocate memory
Mark Lobodzinski23065352015-05-29 09:32:35 -0500452 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500453 ASSERT_VK_SUCCESS(err);
454
455 // Try to bind free memory that has been freed
Mark Lobodzinski23065352015-05-29 09:32:35 -0500456 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500457 ASSERT_VK_SUCCESS(err);
458
459 // Map memory as if to initialize the image
460 void *mappedAddress = NULL;
Mark Lobodzinski23065352015-05-29 09:32:35 -0500461 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500462
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600463 msgFlags = m_errorMonitor->GetState(&msgString);
464 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to map memory not visible to CPU";
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500465 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
466 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
467 }
468}
469
470TEST_F(VkLayerTest, BindInvalidMemory)
471{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600472 VkFlags msgFlags;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500473 std::string msgString;
474 VkResult err;
475
476 ASSERT_NO_FATAL_FAILURE(InitState());
477 m_errorMonitor->ClearState();
478
479 // Create an image, allocate memory, free it, and then try to bind it
480 VkImage image;
Mark Lobodzinski23065352015-05-29 09:32:35 -0500481 VkDeviceMemory mem;
482 VkMemoryRequirements mem_reqs;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500483
484 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
485 const int32_t tex_width = 32;
486 const int32_t tex_height = 32;
487 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500488
489 const VkImageCreateInfo image_create_info = {
490 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
491 .pNext = NULL,
492 .imageType = VK_IMAGE_TYPE_2D,
493 .format = tex_format,
494 .extent = { tex_width, tex_height, 1 },
495 .mipLevels = 1,
496 .arraySize = 1,
497 .samples = 1,
498 .tiling = VK_IMAGE_TILING_LINEAR,
499 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
500 .flags = 0,
501 };
502 VkMemoryAllocInfo mem_alloc = {
503 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
504 .pNext = NULL,
505 .allocationSize = 0,
506 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
507 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
508 };
509
510 err = vkCreateImage(m_device->device(), &image_create_info, &image);
511 ASSERT_VK_SUCCESS(err);
512
513 err = vkGetObjectInfo(m_device->device(),
514 VK_OBJECT_TYPE_IMAGE,
515 image,
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500516 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
517 &mem_reqs_size,
Mark Lobodzinski23065352015-05-29 09:32:35 -0500518 &mem_reqs);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500519 ASSERT_VK_SUCCESS(err);
520
Mark Lobodzinski23065352015-05-29 09:32:35 -0500521 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500522
523 // allocate memory
Mark Lobodzinski23065352015-05-29 09:32:35 -0500524 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500525 ASSERT_VK_SUCCESS(err);
526
527 // Introduce validation failure, free memory before binding
Mark Lobodzinski23065352015-05-29 09:32:35 -0500528 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500529 ASSERT_VK_SUCCESS(err);
530
531 // Try to bind free memory that has been freed
Mark Lobodzinski23065352015-05-29 09:32:35 -0500532 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500533 ASSERT_VK_SUCCESS(err);
534
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600535 msgFlags = m_errorMonitor->GetState(&msgString);
536 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to bind a freed memory object";
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500537 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500538 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
539 }
540}
541
542TEST_F(VkLayerTest, FreeBoundMemory)
543{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600544 VkFlags msgFlags;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500545 std::string msgString;
546 VkResult err;
547
548 ASSERT_NO_FATAL_FAILURE(InitState());
549 m_errorMonitor->ClearState();
550
551 // Create an image, allocate memory, free it, and then try to bind it
552 VkImage image;
Mark Lobodzinski23065352015-05-29 09:32:35 -0500553 VkDeviceMemory mem;
554 VkMemoryRequirements mem_reqs;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500555
556 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
557 const int32_t tex_width = 32;
558 const int32_t tex_height = 32;
559 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500560
561 const VkImageCreateInfo image_create_info = {
562 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
563 .pNext = NULL,
564 .imageType = VK_IMAGE_TYPE_2D,
565 .format = tex_format,
566 .extent = { tex_width, tex_height, 1 },
567 .mipLevels = 1,
568 .arraySize = 1,
569 .samples = 1,
570 .tiling = VK_IMAGE_TILING_LINEAR,
571 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
572 .flags = 0,
573 };
574 VkMemoryAllocInfo mem_alloc = {
575 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
576 .pNext = NULL,
577 .allocationSize = 0,
578 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
579 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
580 };
581
582 err = vkCreateImage(m_device->device(), &image_create_info, &image);
583 ASSERT_VK_SUCCESS(err);
584
585 err = vkGetObjectInfo(m_device->device(),
586 VK_OBJECT_TYPE_IMAGE,
587 image,
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500588 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
589 &mem_reqs_size,
Mark Lobodzinski23065352015-05-29 09:32:35 -0500590 &mem_reqs);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500591 ASSERT_VK_SUCCESS(err);
592
Mark Lobodzinski23065352015-05-29 09:32:35 -0500593 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500594
595 // allocate memory
Mark Lobodzinski23065352015-05-29 09:32:35 -0500596 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500597 ASSERT_VK_SUCCESS(err);
598
599 // Bind memory to Image object
Mark Lobodzinski23065352015-05-29 09:32:35 -0500600 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500601 ASSERT_VK_SUCCESS(err);
602
603 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23065352015-05-29 09:32:35 -0500604 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500605 ASSERT_VK_SUCCESS(err);
606
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600607 msgFlags = m_errorMonitor->GetState(&msgString);
608 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT) << "Did not receive an warning while tring to free bound memory";
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500609 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
610 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
611 }
612}
613
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500614TEST_F(VkLayerTest, RebindMemory)
615{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600616 VkFlags msgFlags;
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500617 std::string msgString;
618 VkResult err;
619
620 ASSERT_NO_FATAL_FAILURE(InitState());
621 m_errorMonitor->ClearState();
622
623 // Create an image, allocate memory, free it, and then try to bind it
624 VkImage image;
625 VkDeviceMemory mem1;
626 VkDeviceMemory mem2;
627 VkMemoryRequirements mem_reqs;
628
629 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
630 const int32_t tex_width = 32;
631 const int32_t tex_height = 32;
632 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
633
634 const VkImageCreateInfo image_create_info = {
635 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
636 .pNext = NULL,
637 .imageType = VK_IMAGE_TYPE_2D,
638 .format = tex_format,
639 .extent = { tex_width, tex_height, 1 },
640 .mipLevels = 1,
641 .arraySize = 1,
642 .samples = 1,
643 .tiling = VK_IMAGE_TILING_LINEAR,
644 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
645 .flags = 0,
646 };
647 VkMemoryAllocInfo mem_alloc = {
648 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
649 .pNext = NULL,
650 .allocationSize = 0,
651 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
652 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
653 };
654
655 err = vkCreateImage(m_device->device(), &image_create_info, &image);
656 ASSERT_VK_SUCCESS(err);
657
658 err = vkGetObjectInfo(m_device->device(),
659 VK_OBJECT_TYPE_IMAGE,
660 image,
661 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
662 &mem_reqs_size,
663 &mem_reqs);
664 ASSERT_VK_SUCCESS(err);
665
666 mem_alloc.allocationSize = mem_reqs.size;
667
668 // allocate 2 memory objects
669 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
670 ASSERT_VK_SUCCESS(err);
671 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
672 ASSERT_VK_SUCCESS(err);
673
674 // Bind first memory object to Image object
675 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
676 ASSERT_VK_SUCCESS(err);
677
678 // Introduce validation failure, try to bind a different memory object to the same image object
679 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
680 ASSERT_VK_SUCCESS(err);
681
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600682 msgFlags = m_errorMonitor->GetState(&msgString);
683 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to rebind an object";
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500684 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
685 FAIL() << "Error received did not match expected message when rebinding memory to an object";
686 }
687}
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500688
689TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
690{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600691 VkFlags msgFlags;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500692 std::string msgString;
693 VkResult err;
694
695 ASSERT_NO_FATAL_FAILURE(InitState());
696 m_errorMonitor->ClearState();
697
698 // Create an image object, allocate memory, destroy the object and then try to bind it
699 VkImage image;
Mark Lobodzinski23065352015-05-29 09:32:35 -0500700 VkDeviceMemory mem;
701 VkMemoryRequirements mem_reqs;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500702
703 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
704 const int32_t tex_width = 32;
705 const int32_t tex_height = 32;
706 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500707
708 const VkImageCreateInfo image_create_info = {
709 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
710 .pNext = NULL,
711 .imageType = VK_IMAGE_TYPE_2D,
712 .format = tex_format,
713 .extent = { tex_width, tex_height, 1 },
714 .mipLevels = 1,
715 .arraySize = 1,
716 .samples = 1,
717 .tiling = VK_IMAGE_TILING_LINEAR,
718 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
719 .flags = 0,
720 };
721 VkMemoryAllocInfo mem_alloc = {
722 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
723 .pNext = NULL,
724 .allocationSize = 0,
725 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
726 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
727 };
728
729 err = vkCreateImage(m_device->device(), &image_create_info, &image);
730 ASSERT_VK_SUCCESS(err);
731
732 err = vkGetObjectInfo(m_device->device(),
733 VK_OBJECT_TYPE_IMAGE,
734 image,
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500735 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
736 &mem_reqs_size,
Mark Lobodzinski23065352015-05-29 09:32:35 -0500737 &mem_reqs);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500738 ASSERT_VK_SUCCESS(err);
739
Mark Lobodzinski23065352015-05-29 09:32:35 -0500740 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500741
742 // Allocate memory
Mark Lobodzinski23065352015-05-29 09:32:35 -0500743 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500744 ASSERT_VK_SUCCESS(err);
745
746 // Introduce validation failure, destroy Image object before binding
747 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
748 ASSERT_VK_SUCCESS(err);
749
750 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23065352015-05-29 09:32:35 -0500751 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500752 ASSERT_VK_SUCCESS(err);
753
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600754 msgFlags = m_errorMonitor->GetState(&msgString);
755 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while binding memory to a destroyed object";
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500756 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500757 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
758 }
759}
760
Tony Barbour0b4d9562015-04-09 10:48:04 -0600761TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour300a6082015-04-07 13:44:53 -0600762{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600763 vk_testing::Fence testFence;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600764 VkFlags msgFlags;
Tony Barbour300a6082015-04-07 13:44:53 -0600765 std::string msgString;
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600766
767 VkFenceCreateInfo fenceInfo = {};
Tony Barbour0b4d9562015-04-09 10:48:04 -0600768 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
769 fenceInfo.pNext = NULL;
770 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour300a6082015-04-07 13:44:53 -0600771
Tony Barbour300a6082015-04-07 13:44:53 -0600772 ASSERT_NO_FATAL_FAILURE(InitState());
773 ASSERT_NO_FATAL_FAILURE(InitViewport());
774 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
775
Tony Barbour6918cd52015-04-09 12:58:51 -0600776 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour300a6082015-04-07 13:44:53 -0600777 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
778
Tony Barbour0b4d9562015-04-09 10:48:04 -0600779 BeginCommandBuffer(cmdBuffer);
Tony Barbour300a6082015-04-07 13:44:53 -0600780 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour0b4d9562015-04-09 10:48:04 -0600781 EndCommandBuffer(cmdBuffer);
Tony Barbour300a6082015-04-07 13:44:53 -0600782
783 testFence.init(*m_device, fenceInfo);
784 m_errorMonitor->ClearState();
Tony Barbour0b4d9562015-04-09 10:48:04 -0600785 cmdBuffer.QueueCommandBuffer(testFence.obj());
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600786 msgFlags = m_errorMonitor->GetState(&msgString);
787 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
Tony Barbour0b4d9562015-04-09 10:48:04 -0600788 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500789 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour0b4d9562015-04-09 10:48:04 -0600790 }
791
792}
793
794TEST_F(VkLayerTest, ResetUnsignaledFence)
795{
796 vk_testing::Fence testFence;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600797 VkFlags msgFlags;
Tony Barbour0b4d9562015-04-09 10:48:04 -0600798 std::string msgString;
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600799 VkFenceCreateInfo fenceInfo = {};
Tony Barbour0b4d9562015-04-09 10:48:04 -0600800 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
801 fenceInfo.pNext = NULL;
802
Tony Barbour0b4d9562015-04-09 10:48:04 -0600803 ASSERT_NO_FATAL_FAILURE(InitState());
804 testFence.init(*m_device, fenceInfo);
805 m_errorMonitor->ClearState();
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600806 VkFence fences[1] = {testFence.obj()};
Tony Barbour0b4d9562015-04-09 10:48:04 -0600807 vkResetFences(m_device->device(), 1, fences);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600808 msgFlags = m_errorMonitor->GetState(&msgString);
809 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from submitting fence with UNSIGNALED state to vkResetFences";
Tony Barbour6918cd52015-04-09 12:58:51 -0600810 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500811 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour0b4d9562015-04-09 10:48:04 -0600812 }
Tony Barbour300a6082015-04-07 13:44:53 -0600813
814}
Tobin Ehlis0788f522015-05-26 16:11:58 -0600815#endif
816#if OBJECT_TRACKER_TESTS
Tony Barbour806c9062015-04-22 15:12:07 -0600817
Tony Barbourd866ad02015-05-06 09:35:56 -0600818TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
819{
820 VkEventCreateInfo event_info;
821 VkEvent event;
822 VkMemoryRequirements mem_req;
823 size_t data_size = sizeof(mem_req);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600824 VkFlags msgFlags;
Tony Barbourd866ad02015-05-06 09:35:56 -0600825 std::string msgString;
826 VkResult err;
827
828 ASSERT_NO_FATAL_FAILURE(InitState());
829 memset(&event_info, 0, sizeof(event_info));
830 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
831
832 err = vkCreateEvent(device(), &event_info, &event);
833 ASSERT_VK_SUCCESS(err);
834 m_errorMonitor->ClearState();
835 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
836 &data_size, &mem_req);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600837 msgFlags = m_errorMonitor->GetState(&msgString);
838 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from mismatched types in vkGetObjectInfo";
Tony Barbourd866ad02015-05-06 09:35:56 -0600839 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500840 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourd866ad02015-05-06 09:35:56 -0600841 }
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500842}
Tony Barbourd866ad02015-05-06 09:35:56 -0600843
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500844TEST_F(VkLayerTest, RasterStateNotBound)
845{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600846 VkFlags msgFlags;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500847 std::string msgString;
848
849 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
850
851 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
852
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600853 msgFlags = m_errorMonitor->GetState(&msgString);
854 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500855 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
856 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
857 }
858}
859
860TEST_F(VkLayerTest, ViewportStateNotBound)
861{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600862 VkFlags msgFlags;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500863 std::string msgString;
864 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
865
866 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
867
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600868 msgFlags = m_errorMonitor->GetState(&msgString);
869 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500870 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
871 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
872 }
873}
874
875TEST_F(VkLayerTest, ColorBlendStateNotBound)
876{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600877 VkFlags msgFlags;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500878 std::string msgString;
879
880 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
881
882 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
883
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600884 msgFlags = m_errorMonitor->GetState(&msgString);
885 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500886 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
887 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
888 }
889}
890
891TEST_F(VkLayerTest, DepthStencilStateNotBound)
892{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600893 VkFlags msgFlags;
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500894 std::string msgString;
895
896 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
897
898 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
899
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600900 msgFlags = m_errorMonitor->GetState(&msgString);
901 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
Mark Lobodzinski3780e142015-05-14 15:08:13 -0500902 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
903 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
904 }
Tony Barbourd866ad02015-05-06 09:35:56 -0600905}
Tobin Ehlis0788f522015-05-26 16:11:58 -0600906#endif
907#if DRAW_STATE_TESTS
Tobin Ehlis49eb23d2015-05-22 12:38:55 -0600908TEST_F(VkLayerTest, PipelineNotBound)
909{
910 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600911 VkFlags msgFlags;
Tobin Ehlis7d1a7112015-05-27 14:32:28 -0600912 std::string msgString;
913
914 ASSERT_NO_FATAL_FAILURE(InitState());
915 m_errorMonitor->ClearState();
916 VkCommandBufferObj cmdBuffer(m_device);
917 BeginCommandBuffer(cmdBuffer);
918 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
919 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600920 msgFlags = m_errorMonitor->GetState(&msgString);
921 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
Tobin Ehlis7d1a7112015-05-27 14:32:28 -0600922 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
923 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
924 }
Tobin Ehlis49eb23d2015-05-22 12:38:55 -0600925}
926
927TEST_F(VkLayerTest, InvalidDescriptorPool)
928{
929 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
930 // The DS check for this is after driver has been called to validate DS internal data struct
931 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600932/* VkFlags msgFlags;
Tobin Ehlis49eb23d2015-05-22 12:38:55 -0600933 std::string msgString;
934 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
935 vkResetDescriptorPool(device(), badPool);
936
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600937 msgFlags = m_errorMonitor->GetState(&msgString);
938 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
Tobin Ehlis49eb23d2015-05-22 12:38:55 -0600939 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
940 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
941 }*/
942}
943
944TEST_F(VkLayerTest, InvalidDescriptorSet)
945{
Tobin Ehlis7d1a7112015-05-27 14:32:28 -0600946 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
947 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis49eb23d2015-05-22 12:38:55 -0600948 // Create a valid cmd buffer
949 // call vkCmdBindDescriptorSets w/ false DS
950}
951
952TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
953{
954 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
955 // The DS check for this is after driver has been called to validate DS internal data struct
956}
957
958TEST_F(VkLayerTest, InvalidPipeline)
959{
Tobin Ehlis7d1a7112015-05-27 14:32:28 -0600960 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
961 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis49eb23d2015-05-22 12:38:55 -0600962 // Create a valid cmd buffer
963 // call vkCmdBindPipeline w/ false Pipeline
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600964 VkFlags msgFlags;
Tobin Ehlis0788f522015-05-26 16:11:58 -0600965 std::string msgString;
966
967 ASSERT_NO_FATAL_FAILURE(InitState());
968 m_errorMonitor->ClearState();
969 VkCommandBufferObj cmdBuffer(m_device);
970 BeginCommandBuffer(cmdBuffer);
971 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
972 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600973 msgFlags = m_errorMonitor->GetState(&msgString);
974 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
Tobin Ehlis0788f522015-05-26 16:11:58 -0600975 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
976 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
977 }
Tobin Ehlis49eb23d2015-05-22 12:38:55 -0600978}
979
Tobin Ehlis7d1a7112015-05-27 14:32:28 -0600980TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis49eb23d2015-05-22 12:38:55 -0600981{
Tobin Ehlis7d1a7112015-05-27 14:32:28 -0600982 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600983 VkFlags msgFlags;
Tobin Ehlis7d1a7112015-05-27 14:32:28 -0600984 std::string msgString;
985 VkResult err;
986
987 ASSERT_NO_FATAL_FAILURE(InitState());
988 m_errorMonitor->ClearState();
989 VkCommandBufferObj cmdBuffer(m_device);
990 const VkDescriptorTypeCount ds_type_count = {
991 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
992 .count = 1,
993 };
994 const VkDescriptorPoolCreateInfo ds_pool_ci = {
995 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
996 .pNext = NULL,
997 .count = 1,
998 .pTypeCount = &ds_type_count,
999 };
1000 VkDescriptorPool ds_pool;
1001 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1002 ASSERT_VK_SUCCESS(err);
Tobin Ehlis7d1a7112015-05-27 14:32:28 -06001003
1004 const VkDescriptorSetLayoutBinding dsl_binding = {
1005 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wu712bb5d2015-05-25 16:22:52 +08001006 .arraySize = 1,
Tobin Ehlis7d1a7112015-05-27 14:32:28 -06001007 .stageFlags = VK_SHADER_STAGE_ALL,
1008 .pImmutableSamplers = NULL,
1009 };
1010
1011 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1012 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1013 .pNext = NULL,
1014 .count = 1,
1015 .pBinding = &dsl_binding,
1016 };
1017 VkDescriptorSetLayout ds_layout;
1018 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1019 ASSERT_VK_SUCCESS(err);
1020
1021 VkDescriptorSet descriptorSet;
1022 uint32_t ds_count = 0;
1023 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1024 ASSERT_VK_SUCCESS(err);
1025
1026 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1027 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1028 .pNext = NULL,
1029 .descriptorSetCount = 1,
1030 .pSetLayouts = &ds_layout,
1031 };
1032
1033 VkPipelineLayout pipeline_layout;
1034 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1035 ASSERT_VK_SUCCESS(err);
1036
1037 size_t shader_len = strlen(bindStateVertShaderText);
1038 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1039 void* pCode = malloc(codeSize);
1040
1041 /* try version 0 first: VkShaderStage followed by GLSL */
1042 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1043 ((uint32_t *) pCode)[1] = 0;
1044 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1045 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1046
1047 const VkShaderCreateInfo vs_ci = {
1048 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1049 .pNext = NULL,
1050 .codeSize = codeSize,
1051 .pCode = pCode,
1052 .flags = 0,
1053 };
1054 VkShader vs;
1055 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1056 ASSERT_VK_SUCCESS(err);
1057
1058 const VkPipelineShader vs_pipe_shader = {
1059 .stage = VK_SHADER_STAGE_VERTEX,
1060 .shader = vs,
1061 .linkConstBufferCount = 0,
1062 .pLinkConstBufferInfo = NULL,
1063 .pSpecializationInfo = NULL,
1064 };
1065 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1066 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1067 .pNext = NULL,
1068 .shader = vs_pipe_shader,
1069 };
1070 const VkGraphicsPipelineCreateInfo gp_ci = {
1071 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1072 .pNext = &pipe_vs_ci,
1073 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1074 .layout = pipeline_layout,
1075 };
1076
1077 VkPipeline pipeline;
1078 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1079 ASSERT_VK_SUCCESS(err);
1080
1081 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1082 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1083
1084 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1085 m_device->get_device_queue();
1086 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1087
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001088 msgFlags = m_errorMonitor->GetState(&msgString);
1089 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
Tobin Ehlis7d1a7112015-05-27 14:32:28 -06001090 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1091 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1092 }
Tobin Ehlis49eb23d2015-05-22 12:38:55 -06001093}
1094
1095TEST_F(VkLayerTest, InvalidDynamicStateObject)
1096{
1097 // Create a valid cmd buffer
1098 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis7d1a7112015-05-27 14:32:28 -06001099 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1100 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis49eb23d2015-05-22 12:38:55 -06001101}
Tobin Ehlis1056d452015-05-27 14:55:35 -06001102
Tobin Ehlis49eb23d2015-05-22 12:38:55 -06001103TEST_F(VkLayerTest, VtxBufferBadIndex)
1104{
1105 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001106 VkFlags msgFlags;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001107 std::string msgString;
1108 VkResult err;
1109
1110 ASSERT_NO_FATAL_FAILURE(InitState());
1111 m_errorMonitor->ClearState();
1112 VkCommandBufferObj cmdBuffer(m_device);
1113 const VkDescriptorTypeCount ds_type_count = {
1114 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1115 .count = 1,
1116 };
1117 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1118 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1119 .pNext = NULL,
1120 .count = 1,
1121 .pTypeCount = &ds_type_count,
1122 };
1123 VkDescriptorPool ds_pool;
1124 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1125 ASSERT_VK_SUCCESS(err);
Tobin Ehlis3b780662015-05-28 12:11:26 -06001126
1127 const VkDescriptorSetLayoutBinding dsl_binding = {
1128 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wu712bb5d2015-05-25 16:22:52 +08001129 .arraySize = 1,
Tobin Ehlis3b780662015-05-28 12:11:26 -06001130 .stageFlags = VK_SHADER_STAGE_ALL,
1131 .pImmutableSamplers = NULL,
1132 };
1133
1134 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1135 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1136 .pNext = NULL,
1137 .count = 1,
1138 .pBinding = &dsl_binding,
1139 };
1140 VkDescriptorSetLayout ds_layout;
1141 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1142 ASSERT_VK_SUCCESS(err);
1143
1144 VkDescriptorSet descriptorSet;
1145 uint32_t ds_count = 0;
1146 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1147 ASSERT_VK_SUCCESS(err);
1148
1149 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1150 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1151 .pNext = NULL,
1152 .descriptorSetCount = 1,
1153 .pSetLayouts = &ds_layout,
1154 };
1155
1156 VkPipelineLayout pipeline_layout;
1157 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1158 ASSERT_VK_SUCCESS(err);
1159
1160 size_t shader_len = strlen(bindStateVertShaderText);
1161 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1162 void* pCode = malloc(codeSize);
1163
1164 /* try version 0 first: VkShaderStage followed by GLSL */
1165 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1166 ((uint32_t *) pCode)[1] = 0;
1167 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1168 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1169
1170 const VkShaderCreateInfo vs_ci = {
1171 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1172 .pNext = NULL,
1173 .codeSize = codeSize,
1174 .pCode = pCode,
1175 .flags = 0,
1176 };
1177 VkShader vs;
1178 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1179
1180 const VkPipelineShader vs_pipe_shader = {
1181 .stage = VK_SHADER_STAGE_VERTEX,
1182 .shader = vs,
1183 .linkConstBufferCount = 0,
1184 .pLinkConstBufferInfo = NULL,
1185 .pSpecializationInfo = NULL,
1186 };
1187 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1188 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1189 .pNext = NULL,
1190 .shader = vs_pipe_shader,
1191 };
1192 const VkGraphicsPipelineCreateInfo gp_ci = {
1193 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1194 .pNext = &pipe_vs_ci,
1195 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1196 .layout = pipeline_layout,
1197 };
1198
1199 VkPipeline pipeline;
1200 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1201 ASSERT_VK_SUCCESS(err);
1202
1203 err= cmdBuffer.BeginCommandBuffer();
1204 ASSERT_VK_SUCCESS(err);
1205 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1206 // Should error before calling to driver so don't care about actual data
1207 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1208
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001209 msgFlags = m_errorMonitor->GetState(&msgString);
1210 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
Tobin Ehlis3b780662015-05-28 12:11:26 -06001211 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1212 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1213 }
Tobin Ehlis49eb23d2015-05-22 12:38:55 -06001214}
1215
1216TEST_F(VkLayerTest, DSTypeMismatch)
1217{
1218 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001219 VkFlags msgFlags;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001220 std::string msgString;
1221 VkResult err;
1222
1223 ASSERT_NO_FATAL_FAILURE(InitState());
1224 m_errorMonitor->ClearState();
1225 //VkDescriptorSetObj descriptorSet(m_device);
1226 const VkDescriptorTypeCount ds_type_count = {
1227 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1228 .count = 1,
1229 };
1230 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1231 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1232 .pNext = NULL,
1233 .count = 1,
1234 .pTypeCount = &ds_type_count,
1235 };
1236 VkDescriptorPool ds_pool;
1237 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1238 ASSERT_VK_SUCCESS(err);
1239 const VkDescriptorSetLayoutBinding dsl_binding = {
1240 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wu712bb5d2015-05-25 16:22:52 +08001241 .arraySize = 1,
Tobin Ehlis3b780662015-05-28 12:11:26 -06001242 .stageFlags = VK_SHADER_STAGE_ALL,
1243 .pImmutableSamplers = NULL,
1244 };
1245
1246 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1247 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1248 .pNext = NULL,
1249 .count = 1,
1250 .pBinding = &dsl_binding,
1251 };
1252 VkDescriptorSetLayout ds_layout;
1253 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1254 ASSERT_VK_SUCCESS(err);
1255
1256 VkDescriptorSet descriptorSet;
1257 uint32_t ds_count = 0;
1258 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1259 ASSERT_VK_SUCCESS(err);
Tobin Ehlis3b780662015-05-28 12:11:26 -06001260
1261 const VkSamplerCreateInfo sampler_ci = {
1262 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1263 .pNext = NULL,
1264 .magFilter = VK_TEX_FILTER_NEAREST,
1265 .minFilter = VK_TEX_FILTER_NEAREST,
1266 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1267 .addressU = VK_TEX_ADDRESS_CLAMP,
1268 .addressV = VK_TEX_ADDRESS_CLAMP,
1269 .addressW = VK_TEX_ADDRESS_CLAMP,
1270 .mipLodBias = 1.0,
1271 .maxAnisotropy = 1,
1272 .compareOp = VK_COMPARE_OP_NEVER,
1273 .minLod = 1.0,
1274 .maxLod = 1.0,
1275 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1276 };
1277 VkSampler sampler;
1278 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1279 ASSERT_VK_SUCCESS(err);
1280
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001281 VkDescriptorInfo descriptor_info;
1282 memset(&descriptor_info, 0, sizeof(descriptor_info));
1283 descriptor_info.sampler = sampler;
1284
1285 VkWriteDescriptorSet descriptor_write;
1286 memset(&descriptor_write, 0, sizeof(descriptor_write));
1287 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1288 descriptor_write.destSet = descriptorSet;
1289 descriptor_write.count = 1;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001290 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001291 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1292 descriptor_write.pDescriptors = &descriptor_info;
1293
1294 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1295
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001296 msgFlags = m_errorMonitor->GetState(&msgString);
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001297 std::cout << msgString << "\n";
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001298 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating BUFFER Descriptor w/ incorrect type of SAMPLER.";
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001299 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1300 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match overlapping binding type!'";
Tobin Ehlis3b780662015-05-28 12:11:26 -06001301 }
Tobin Ehlis49eb23d2015-05-22 12:38:55 -06001302}
1303
1304TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1305{
1306 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001307 VkFlags msgFlags;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001308 std::string msgString;
1309 VkResult err;
1310
1311 ASSERT_NO_FATAL_FAILURE(InitState());
1312 m_errorMonitor->ClearState();
1313 //VkDescriptorSetObj descriptorSet(m_device);
1314 const VkDescriptorTypeCount ds_type_count = {
1315 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1316 .count = 1,
1317 };
1318 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1319 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1320 .pNext = NULL,
1321 .count = 1,
1322 .pTypeCount = &ds_type_count,
1323 };
1324 VkDescriptorPool ds_pool;
1325 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1326 ASSERT_VK_SUCCESS(err);
1327 const VkDescriptorSetLayoutBinding dsl_binding = {
1328 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wu712bb5d2015-05-25 16:22:52 +08001329 .arraySize = 1,
Tobin Ehlis3b780662015-05-28 12:11:26 -06001330 .stageFlags = VK_SHADER_STAGE_ALL,
1331 .pImmutableSamplers = NULL,
1332 };
1333
1334 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1335 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1336 .pNext = NULL,
1337 .count = 1,
1338 .pBinding = &dsl_binding,
1339 };
1340 VkDescriptorSetLayout ds_layout;
1341 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1342 ASSERT_VK_SUCCESS(err);
1343
1344 VkDescriptorSet descriptorSet;
1345 uint32_t ds_count = 0;
1346 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1347 ASSERT_VK_SUCCESS(err);
Tobin Ehlis3b780662015-05-28 12:11:26 -06001348
1349 const VkSamplerCreateInfo sampler_ci = {
1350 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1351 .pNext = NULL,
1352 .magFilter = VK_TEX_FILTER_NEAREST,
1353 .minFilter = VK_TEX_FILTER_NEAREST,
1354 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1355 .addressU = VK_TEX_ADDRESS_CLAMP,
1356 .addressV = VK_TEX_ADDRESS_CLAMP,
1357 .addressW = VK_TEX_ADDRESS_CLAMP,
1358 .mipLodBias = 1.0,
1359 .maxAnisotropy = 1,
1360 .compareOp = VK_COMPARE_OP_NEVER,
1361 .minLod = 1.0,
1362 .maxLod = 1.0,
1363 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1364 };
1365 VkSampler sampler;
1366 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1367 ASSERT_VK_SUCCESS(err);
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001368
1369 VkDescriptorInfo descriptor_info;
1370 memset(&descriptor_info, 0, sizeof(descriptor_info));
1371 descriptor_info.sampler = sampler;
1372
1373 VkWriteDescriptorSet descriptor_write;
1374 memset(&descriptor_write, 0, sizeof(descriptor_write));
1375 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1376 descriptor_write.destSet = descriptorSet;
1377 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1378 descriptor_write.count = 1;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001379 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001380 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1381 descriptor_write.pDescriptors = &descriptor_info;
1382
1383 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1384
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001385 msgFlags = m_errorMonitor->GetState(&msgString);
1386 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ index out of bounds.";
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001387 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1388 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding...'";
Tobin Ehlis3b780662015-05-28 12:11:26 -06001389 }
Tobin Ehlis49eb23d2015-05-22 12:38:55 -06001390}
1391
1392TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1393{
Tobin Ehlis3b780662015-05-28 12:11:26 -06001394 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001395 VkFlags msgFlags;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001396 std::string msgString;
1397 VkResult err;
1398
1399 ASSERT_NO_FATAL_FAILURE(InitState());
1400 m_errorMonitor->ClearState();
1401 //VkDescriptorSetObj descriptorSet(m_device);
1402 const VkDescriptorTypeCount ds_type_count = {
1403 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1404 .count = 1,
1405 };
1406 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1407 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1408 .pNext = NULL,
1409 .count = 1,
1410 .pTypeCount = &ds_type_count,
1411 };
1412 VkDescriptorPool ds_pool;
1413 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1414 ASSERT_VK_SUCCESS(err);
1415 const VkDescriptorSetLayoutBinding dsl_binding = {
1416 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wu712bb5d2015-05-25 16:22:52 +08001417 .arraySize = 1,
Tobin Ehlis3b780662015-05-28 12:11:26 -06001418 .stageFlags = VK_SHADER_STAGE_ALL,
1419 .pImmutableSamplers = NULL,
1420 };
1421
1422 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1423 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1424 .pNext = NULL,
1425 .count = 1,
1426 .pBinding = &dsl_binding,
1427 };
1428 VkDescriptorSetLayout ds_layout;
1429 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1430 ASSERT_VK_SUCCESS(err);
1431
1432 VkDescriptorSet descriptorSet;
1433 uint32_t ds_count = 0;
1434 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1435 ASSERT_VK_SUCCESS(err);
Tobin Ehlis3b780662015-05-28 12:11:26 -06001436
1437 const VkSamplerCreateInfo sampler_ci = {
1438 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1439 .pNext = NULL,
1440 .magFilter = VK_TEX_FILTER_NEAREST,
1441 .minFilter = VK_TEX_FILTER_NEAREST,
1442 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1443 .addressU = VK_TEX_ADDRESS_CLAMP,
1444 .addressV = VK_TEX_ADDRESS_CLAMP,
1445 .addressW = VK_TEX_ADDRESS_CLAMP,
1446 .mipLodBias = 1.0,
1447 .maxAnisotropy = 1,
1448 .compareOp = VK_COMPARE_OP_NEVER,
1449 .minLod = 1.0,
1450 .maxLod = 1.0,
1451 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1452 };
1453 VkSampler sampler;
1454 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1455 ASSERT_VK_SUCCESS(err);
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001456
1457 VkDescriptorInfo descriptor_info;
1458 memset(&descriptor_info, 0, sizeof(descriptor_info));
1459 descriptor_info.sampler = sampler;
1460
1461 VkWriteDescriptorSet descriptor_write;
1462 memset(&descriptor_write, 0, sizeof(descriptor_write));
1463 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1464 descriptor_write.destSet = descriptorSet;
1465 descriptor_write.destBinding = 2;
1466 descriptor_write.count = 1;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001467 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001468 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1469 descriptor_write.pDescriptors = &descriptor_info;
1470
1471 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1472
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001473 msgFlags = m_errorMonitor->GetState(&msgString);
1474 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ count too large for layout.";
Tobin Ehlis3b780662015-05-28 12:11:26 -06001475 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1476 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1477 }
Tobin Ehlis49eb23d2015-05-22 12:38:55 -06001478}
1479
1480TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1481{
1482 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001483 VkFlags msgFlags;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001484 std::string msgString;
1485 VkResult err;
1486
1487 ASSERT_NO_FATAL_FAILURE(InitState());
1488 m_errorMonitor->ClearState();
1489 //VkDescriptorSetObj descriptorSet(m_device);
1490 const VkDescriptorTypeCount ds_type_count = {
1491 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1492 .count = 1,
1493 };
1494 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1495 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1496 .pNext = NULL,
1497 .count = 1,
1498 .pTypeCount = &ds_type_count,
1499 };
1500 VkDescriptorPool ds_pool;
1501 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1502 ASSERT_VK_SUCCESS(err);
1503 const VkDescriptorSetLayoutBinding dsl_binding = {
1504 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wu712bb5d2015-05-25 16:22:52 +08001505 .arraySize = 1,
Tobin Ehlis3b780662015-05-28 12:11:26 -06001506 .stageFlags = VK_SHADER_STAGE_ALL,
1507 .pImmutableSamplers = NULL,
1508 };
1509
1510 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1511 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1512 .pNext = NULL,
1513 .count = 1,
1514 .pBinding = &dsl_binding,
1515 };
1516 VkDescriptorSetLayout ds_layout;
1517 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1518 ASSERT_VK_SUCCESS(err);
1519
1520 VkDescriptorSet descriptorSet;
1521 uint32_t ds_count = 0;
1522 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1523 ASSERT_VK_SUCCESS(err);
Tobin Ehlis3b780662015-05-28 12:11:26 -06001524
1525 const VkSamplerCreateInfo sampler_ci = {
1526 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1527 .pNext = NULL,
1528 .magFilter = VK_TEX_FILTER_NEAREST,
1529 .minFilter = VK_TEX_FILTER_NEAREST,
1530 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1531 .addressU = VK_TEX_ADDRESS_CLAMP,
1532 .addressV = VK_TEX_ADDRESS_CLAMP,
1533 .addressW = VK_TEX_ADDRESS_CLAMP,
1534 .mipLodBias = 1.0,
1535 .maxAnisotropy = 1,
1536 .compareOp = VK_COMPARE_OP_NEVER,
1537 .minLod = 1.0,
1538 .maxLod = 1.0,
1539 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1540 };
1541 VkSampler sampler;
1542 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1543 ASSERT_VK_SUCCESS(err);
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001544
1545
1546 VkDescriptorInfo descriptor_info;
1547 memset(&descriptor_info, 0, sizeof(descriptor_info));
1548 descriptor_info.sampler = sampler;
1549
1550 VkWriteDescriptorSet descriptor_write;
1551 memset(&descriptor_write, 0, sizeof(descriptor_write));
1552 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1553 descriptor_write.destSet = descriptorSet;
1554 descriptor_write.count = 1;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001555 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu9d00ed72015-05-25 16:27:55 +08001556 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1557 descriptor_write.pDescriptors = &descriptor_info;
1558
1559 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1560
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001561 msgFlags = m_errorMonitor->GetState(&msgString);
1562 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ invalid struct type.";
Tobin Ehlis3b780662015-05-28 12:11:26 -06001563 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1564 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1565 }
Tobin Ehlis49eb23d2015-05-22 12:38:55 -06001566}
1567
1568TEST_F(VkLayerTest, NumSamplesMismatch)
1569{
Tobin Ehlis3b780662015-05-28 12:11:26 -06001570 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001571 VkFlags msgFlags;
Tobin Ehlis3b780662015-05-28 12:11:26 -06001572 std::string msgString;
1573 VkResult err;
1574
1575 ASSERT_NO_FATAL_FAILURE(InitState());
1576 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1577 m_errorMonitor->ClearState();
1578 VkCommandBufferObj cmdBuffer(m_device);
1579 const VkDescriptorTypeCount ds_type_count = {
1580 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1581 .count = 1,
1582 };
1583 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1584 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1585 .pNext = NULL,
1586 .count = 1,
1587 .pTypeCount = &ds_type_count,
1588 };
1589 VkDescriptorPool ds_pool;
1590 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1591 ASSERT_VK_SUCCESS(err);
Tobin Ehlis3b780662015-05-28 12:11:26 -06001592
1593 const VkDescriptorSetLayoutBinding dsl_binding = {
1594 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wu712bb5d2015-05-25 16:22:52 +08001595 .arraySize = 1,
Tobin Ehlis3b780662015-05-28 12:11:26 -06001596 .stageFlags = VK_SHADER_STAGE_ALL,
1597 .pImmutableSamplers = NULL,
1598 };
1599
1600 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1601 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1602 .pNext = NULL,
1603 .count = 1,
1604 .pBinding = &dsl_binding,
1605 };
1606 VkDescriptorSetLayout ds_layout;
1607 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1608 ASSERT_VK_SUCCESS(err);
1609
1610 VkDescriptorSet descriptorSet;
1611 uint32_t ds_count = 0;
1612 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1613 ASSERT_VK_SUCCESS(err);
1614
1615 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1616 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1617 .pNext = NULL,
Tony Barbour04cd4cc2015-06-03 12:30:49 -06001618 .samples = 4,
Tobin Ehlis3b780662015-05-28 12:11:26 -06001619 .multisampleEnable = 1,
1620 .sampleShadingEnable = 0,
1621 .minSampleShading = 1.0,
1622 .sampleMask = 15,
1623 };
1624
1625 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1626 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1627 .pNext = NULL,
1628 .descriptorSetCount = 1,
1629 .pSetLayouts = &ds_layout,
1630 };
1631
1632 VkPipelineLayout pipeline_layout;
1633 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1634 ASSERT_VK_SUCCESS(err);
1635
1636 size_t shader_len = strlen(bindStateVertShaderText);
1637 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1638 void* pCode = malloc(codeSize);
1639
1640 /* try version 0 first: VkShaderStage followed by GLSL */
1641 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1642 ((uint32_t *) pCode)[1] = 0;
1643 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1644 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1645
1646 const VkShaderCreateInfo vs_ci = {
1647 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1648 .pNext = NULL,
1649 .codeSize = codeSize,
1650 .pCode = pCode,
1651 .flags = 0,
1652 };
1653 VkShader vs;
1654 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1655 ASSERT_VK_SUCCESS(err);
1656
1657 const VkPipelineShader vs_pipe_shader = {
1658 .stage = VK_SHADER_STAGE_VERTEX,
1659 .shader = vs,
1660 .linkConstBufferCount = 0,
1661 .pLinkConstBufferInfo = NULL,
1662 .pSpecializationInfo = NULL,
1663 };
1664 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1665 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1666 .pNext = &pipe_ms_state_ci,
1667 .shader = vs_pipe_shader,
1668 };
1669 const VkGraphicsPipelineCreateInfo gp_ci = {
1670 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1671 .pNext = &pipe_vs_ci,
1672 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1673 .layout = pipeline_layout,
1674 };
1675
1676 VkPipeline pipeline;
1677 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1678 ASSERT_VK_SUCCESS(err);
1679
1680 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1681 BeginCommandBuffer(cmdBuffer);
1682 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1683
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001684 msgFlags = m_errorMonitor->GetState(&msgString);
1685 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
Tobin Ehlis3b780662015-05-28 12:11:26 -06001686 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1687 FAIL() << "Error received was not 'Num samples mismatch!...'";
1688 }
Tobin Ehlis49eb23d2015-05-22 12:38:55 -06001689}
Tobin Ehlis0788f522015-05-26 16:11:58 -06001690#endif
1691#if THREADING_TESTS
Mike Stroyanaccf7692015-05-12 16:00:45 -06001692#if GTEST_IS_THREADSAFE
1693struct thread_data_struct {
1694 VkCmdBuffer cmdBuffer;
1695 VkEvent event;
1696 bool bailout;
1697};
1698
1699extern "C" void *AddToCommandBuffer(void *arg)
1700{
1701 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1702 std::string msgString;
1703
1704 for (int i = 0; i<10000; i++) {
1705 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1706 if (data->bailout) {
1707 break;
1708 }
1709 }
1710 return NULL;
1711}
1712
1713TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1714{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001715 VkFlags msgFlags;
Mike Stroyanaccf7692015-05-12 16:00:45 -06001716 std::string msgString;
1717 pthread_t thread;
1718 pthread_attr_t thread_attr;
1719
1720 ASSERT_NO_FATAL_FAILURE(InitState());
1721 ASSERT_NO_FATAL_FAILURE(InitViewport());
1722 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1723
1724 VkCommandBufferObj cmdBuffer(m_device);
1725
1726 m_errorMonitor->ClearState();
1727 pthread_attr_init(&thread_attr);
1728 BeginCommandBuffer(cmdBuffer);
1729
1730 VkEventCreateInfo event_info;
1731 VkEvent event;
1732 VkMemoryRequirements mem_req;
1733 size_t data_size = sizeof(mem_req);
1734 VkResult err;
1735
1736 memset(&event_info, 0, sizeof(event_info));
1737 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1738
1739 err = vkCreateEvent(device(), &event_info, &event);
1740 ASSERT_VK_SUCCESS(err);
1741
1742 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1743 &data_size, &mem_req);
1744 ASSERT_VK_SUCCESS(err);
1745
1746 VkMemoryAllocInfo mem_info;
1747 VkDeviceMemory event_mem;
1748
1749 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1750
1751 memset(&mem_info, 0, sizeof(mem_info));
1752 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1753 mem_info.allocationSize = mem_req.size;
1754 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1755 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1756 err = vkAllocMemory(device(), &mem_info, &event_mem);
1757 ASSERT_VK_SUCCESS(err);
1758
Mark Lobodzinski23065352015-05-29 09:32:35 -05001759 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyanaccf7692015-05-12 16:00:45 -06001760 ASSERT_VK_SUCCESS(err);
1761
1762 err = vkResetEvent(device(), event);
1763 ASSERT_VK_SUCCESS(err);
1764
1765 struct thread_data_struct data;
1766 data.cmdBuffer = cmdBuffer.obj();
1767 data.event = event;
1768 data.bailout = false;
1769 m_errorMonitor->SetBailout(&data.bailout);
1770 // Add many entries to command buffer from another thread.
1771 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1772 // Add many entries to command buffer from this thread at the same time.
1773 AddToCommandBuffer(&data);
1774 pthread_join(thread, NULL);
1775 EndCommandBuffer(cmdBuffer);
1776
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001777 msgFlags = m_errorMonitor->GetState(&msgString);
1778 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_INFO_BIT) << "Did not receive an err from using one VkCommandBufferObj in two threads";
Mike Stroyanaccf7692015-05-12 16:00:45 -06001779 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski3780e142015-05-14 15:08:13 -05001780 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyanaccf7692015-05-12 16:00:45 -06001781 }
1782
1783}
1784#endif
Tobin Ehlis0788f522015-05-26 16:11:58 -06001785#endif
Chris Forbes9f7ff632015-05-25 11:13:08 +12001786
1787#if SHADER_CHECKER_TESTS
1788TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
1789{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001790 VkFlags msgFlags;
Chris Forbes9f7ff632015-05-25 11:13:08 +12001791 std::string msgString;
1792 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06001793 ScopedUseGlsl useGlsl(false);
Chris Forbes9f7ff632015-05-25 11:13:08 +12001794
1795 char const *vsSource =
1796 "#version 140\n"
1797 "#extension GL_ARB_separate_shader_objects: require\n"
1798 "#extension GL_ARB_shading_language_420pack: require\n"
1799 "\n"
1800 "layout(location=0) out float x;\n"
1801 "void main(){\n"
1802 " gl_Position = vec4(1);\n"
1803 " x = 0;\n"
1804 "}\n";
1805 char const *fsSource =
1806 "#version 140\n"
1807 "#extension GL_ARB_separate_shader_objects: require\n"
1808 "#extension GL_ARB_shading_language_420pack: require\n"
1809 "\n"
1810 "layout(location=0) out vec4 color;\n"
1811 "void main(){\n"
1812 " color = vec4(1);\n"
1813 "}\n";
1814
1815 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1816 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1817
1818 VkPipelineObj pipe(m_device);
1819 pipe.AddShader(&vs);
1820 pipe.AddShader(&fs);
1821
1822 VkCommandBufferObj dummyCmd(m_device);
1823 VkDescriptorSetObj descriptorSet(m_device);
1824 descriptorSet.AppendDummy();
1825 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1826
1827 m_errorMonitor->ClearState();
1828 pipe.CreateVKPipeline(descriptorSet);
1829
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001830 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes9f7ff632015-05-25 11:13:08 +12001831
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001832 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes9f7ff632015-05-25 11:13:08 +12001833 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
1834 FAIL() << "Incorrect warning: " << msgString;
1835 }
1836}
Chris Forbes9f7ff632015-05-25 11:13:08 +12001837
Chris Forbes59cb88d2015-05-25 11:13:13 +12001838TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
1839{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001840 VkFlags msgFlags;
Chris Forbes59cb88d2015-05-25 11:13:13 +12001841 std::string msgString;
1842 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06001843 ScopedUseGlsl useGlsl(false);
Chris Forbes59cb88d2015-05-25 11:13:13 +12001844
1845 char const *vsSource =
1846 "#version 140\n"
1847 "#extension GL_ARB_separate_shader_objects: require\n"
1848 "#extension GL_ARB_shading_language_420pack: require\n"
1849 "\n"
1850 "void main(){\n"
1851 " gl_Position = vec4(1);\n"
1852 "}\n";
1853 char const *fsSource =
1854 "#version 140\n"
1855 "#extension GL_ARB_separate_shader_objects: require\n"
1856 "#extension GL_ARB_shading_language_420pack: require\n"
1857 "\n"
1858 "layout(location=0) in float x;\n"
1859 "layout(location=0) out vec4 color;\n"
1860 "void main(){\n"
1861 " color = vec4(x);\n"
1862 "}\n";
1863
1864 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1865 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1866
1867 VkPipelineObj pipe(m_device);
1868 pipe.AddShader(&vs);
1869 pipe.AddShader(&fs);
1870
1871 VkCommandBufferObj dummyCmd(m_device);
1872 VkDescriptorSetObj descriptorSet(m_device);
1873 descriptorSet.AppendDummy();
1874 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1875
1876 m_errorMonitor->ClearState();
1877 pipe.CreateVKPipeline(descriptorSet);
1878
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001879 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes59cb88d2015-05-25 11:13:13 +12001880
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001881 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes59cb88d2015-05-25 11:13:13 +12001882 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
1883 FAIL() << "Incorrect error: " << msgString;
1884 }
1885}
1886
Chris Forbesb56af562015-05-25 11:13:17 +12001887TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
1888{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001889 VkFlags msgFlags;
Chris Forbesb56af562015-05-25 11:13:17 +12001890 std::string msgString;
1891 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06001892 ScopedUseGlsl useGlsl(false);
Chris Forbesb56af562015-05-25 11:13:17 +12001893
1894 char const *vsSource =
1895 "#version 140\n"
1896 "#extension GL_ARB_separate_shader_objects: require\n"
1897 "#extension GL_ARB_shading_language_420pack: require\n"
1898 "\n"
1899 "layout(location=0) out int x;\n"
1900 "void main(){\n"
1901 " x = 0;\n"
1902 " gl_Position = vec4(1);\n"
1903 "}\n";
1904 char const *fsSource =
1905 "#version 140\n"
1906 "#extension GL_ARB_separate_shader_objects: require\n"
1907 "#extension GL_ARB_shading_language_420pack: require\n"
1908 "\n"
1909 "layout(location=0) in float x;\n" /* VS writes int */
1910 "layout(location=0) out vec4 color;\n"
1911 "void main(){\n"
1912 " color = vec4(x);\n"
1913 "}\n";
1914
1915 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1916 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1917
1918 VkPipelineObj pipe(m_device);
1919 pipe.AddShader(&vs);
1920 pipe.AddShader(&fs);
1921
1922 VkCommandBufferObj dummyCmd(m_device);
1923 VkDescriptorSetObj descriptorSet(m_device);
1924 descriptorSet.AppendDummy();
1925 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1926
1927 m_errorMonitor->ClearState();
1928 pipe.CreateVKPipeline(descriptorSet);
1929
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001930 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesb56af562015-05-25 11:13:17 +12001931
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001932 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesb56af562015-05-25 11:13:17 +12001933 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
1934 FAIL() << "Incorrect error: " << msgString;
1935 }
1936}
1937
Chris Forbesde136e02015-05-25 11:13:28 +12001938TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
1939{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001940 VkFlags msgFlags;
Chris Forbesde136e02015-05-25 11:13:28 +12001941 std::string msgString;
1942 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06001943 ScopedUseGlsl useGlsl(false);
Chris Forbesde136e02015-05-25 11:13:28 +12001944
1945 VkVertexInputBindingDescription input_binding;
1946 memset(&input_binding, 0, sizeof(input_binding));
1947
1948 VkVertexInputAttributeDescription input_attrib;
1949 memset(&input_attrib, 0, sizeof(input_attrib));
1950 input_attrib.format = VK_FORMAT_R32_SFLOAT;
1951
1952 char const *vsSource =
1953 "#version 140\n"
1954 "#extension GL_ARB_separate_shader_objects: require\n"
1955 "#extension GL_ARB_shading_language_420pack: require\n"
1956 "\n"
1957 "void main(){\n"
1958 " gl_Position = vec4(1);\n"
1959 "}\n";
1960 char const *fsSource =
1961 "#version 140\n"
1962 "#extension GL_ARB_separate_shader_objects: require\n"
1963 "#extension GL_ARB_shading_language_420pack: require\n"
1964 "\n"
1965 "layout(location=0) out vec4 color;\n"
1966 "void main(){\n"
1967 " color = vec4(1);\n"
1968 "}\n";
1969
1970 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1971 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1972
1973 VkPipelineObj pipe(m_device);
1974 pipe.AddShader(&vs);
1975 pipe.AddShader(&fs);
1976
1977 pipe.AddVertexInputBindings(&input_binding, 1);
1978 pipe.AddVertexInputAttribs(&input_attrib, 1);
1979
1980 VkCommandBufferObj dummyCmd(m_device);
1981 VkDescriptorSetObj descriptorSet(m_device);
1982 descriptorSet.AppendDummy();
1983 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1984
1985 m_errorMonitor->ClearState();
1986 pipe.CreateVKPipeline(descriptorSet);
1987
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001988 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesde136e02015-05-25 11:13:28 +12001989
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001990 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesde136e02015-05-25 11:13:28 +12001991 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
1992 FAIL() << "Incorrect warning: " << msgString;
1993 }
1994}
1995
Chris Forbes62e8e502015-05-25 11:13:29 +12001996TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
1997{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001998 VkFlags msgFlags;
Chris Forbes62e8e502015-05-25 11:13:29 +12001999 std::string msgString;
2000 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06002001 ScopedUseGlsl useGlsl(false);
Chris Forbes62e8e502015-05-25 11:13:29 +12002002
2003 char const *vsSource =
2004 "#version 140\n"
2005 "#extension GL_ARB_separate_shader_objects: require\n"
2006 "#extension GL_ARB_shading_language_420pack: require\n"
2007 "\n"
2008 "layout(location=0) in vec4 x;\n" /* not provided */
2009 "void main(){\n"
2010 " gl_Position = x;\n"
2011 "}\n";
2012 char const *fsSource =
2013 "#version 140\n"
2014 "#extension GL_ARB_separate_shader_objects: require\n"
2015 "#extension GL_ARB_shading_language_420pack: require\n"
2016 "\n"
2017 "layout(location=0) out vec4 color;\n"
2018 "void main(){\n"
2019 " color = vec4(1);\n"
2020 "}\n";
2021
2022 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2023 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2024
2025 VkPipelineObj pipe(m_device);
2026 pipe.AddShader(&vs);
2027 pipe.AddShader(&fs);
2028
2029 VkCommandBufferObj dummyCmd(m_device);
2030 VkDescriptorSetObj descriptorSet(m_device);
2031 descriptorSet.AppendDummy();
2032 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2033
2034 m_errorMonitor->ClearState();
2035 pipe.CreateVKPipeline(descriptorSet);
2036
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002037 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes62e8e502015-05-25 11:13:29 +12002038
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002039 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes62e8e502015-05-25 11:13:29 +12002040 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2041 FAIL() << "Incorrect warning: " << msgString;
2042 }
2043}
2044
Chris Forbesc97d98e2015-05-25 11:13:31 +12002045TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2046{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002047 VkFlags msgFlags;
Chris Forbesc97d98e2015-05-25 11:13:31 +12002048 std::string msgString;
2049 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06002050 ScopedUseGlsl useGlsl(false);
Chris Forbesc97d98e2015-05-25 11:13:31 +12002051
2052 VkVertexInputBindingDescription input_binding;
2053 memset(&input_binding, 0, sizeof(input_binding));
2054
2055 VkVertexInputAttributeDescription input_attrib;
2056 memset(&input_attrib, 0, sizeof(input_attrib));
2057 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2058
2059 char const *vsSource =
2060 "#version 140\n"
2061 "#extension GL_ARB_separate_shader_objects: require\n"
2062 "#extension GL_ARB_shading_language_420pack: require\n"
2063 "\n"
2064 "layout(location=0) in int x;\n" /* attrib provided float */
2065 "void main(){\n"
2066 " gl_Position = vec4(x);\n"
2067 "}\n";
2068 char const *fsSource =
2069 "#version 140\n"
2070 "#extension GL_ARB_separate_shader_objects: require\n"
2071 "#extension GL_ARB_shading_language_420pack: require\n"
2072 "\n"
2073 "layout(location=0) out vec4 color;\n"
2074 "void main(){\n"
2075 " color = vec4(1);\n"
2076 "}\n";
2077
2078 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2079 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2080
2081 VkPipelineObj pipe(m_device);
2082 pipe.AddShader(&vs);
2083 pipe.AddShader(&fs);
2084
2085 pipe.AddVertexInputBindings(&input_binding, 1);
2086 pipe.AddVertexInputAttribs(&input_attrib, 1);
2087
2088 VkCommandBufferObj dummyCmd(m_device);
2089 VkDescriptorSetObj descriptorSet(m_device);
2090 descriptorSet.AppendDummy();
2091 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2092
2093 m_errorMonitor->ClearState();
2094 pipe.CreateVKPipeline(descriptorSet);
2095
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002096 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc97d98e2015-05-25 11:13:31 +12002097
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002098 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc97d98e2015-05-25 11:13:31 +12002099 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2100 FAIL() << "Incorrect error: " << msgString;
2101 }
2102}
2103
Chris Forbes280ba2c2015-06-12 11:16:41 +12002104TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2105{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002106 VkFlags msgFlags;
Chris Forbes280ba2c2015-06-12 11:16:41 +12002107 std::string msgString;
2108 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06002109 ScopedUseGlsl useGlsl(false);
Chris Forbes280ba2c2015-06-12 11:16:41 +12002110
2111 /* Two binding descriptions for binding 0 */
2112 VkVertexInputBindingDescription input_bindings[2];
2113 memset(input_bindings, 0, sizeof(input_bindings));
2114
2115 VkVertexInputAttributeDescription input_attrib;
2116 memset(&input_attrib, 0, sizeof(input_attrib));
2117 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2118
2119 char const *vsSource =
2120 "#version 140\n"
2121 "#extension GL_ARB_separate_shader_objects: require\n"
2122 "#extension GL_ARB_shading_language_420pack: require\n"
2123 "\n"
2124 "layout(location=0) in float x;\n" /* attrib provided float */
2125 "void main(){\n"
2126 " gl_Position = vec4(x);\n"
2127 "}\n";
2128 char const *fsSource =
2129 "#version 140\n"
2130 "#extension GL_ARB_separate_shader_objects: require\n"
2131 "#extension GL_ARB_shading_language_420pack: require\n"
2132 "\n"
2133 "layout(location=0) out vec4 color;\n"
2134 "void main(){\n"
2135 " color = vec4(1);\n"
2136 "}\n";
2137
2138 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2139 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2140
2141 VkPipelineObj pipe(m_device);
2142 pipe.AddShader(&vs);
2143 pipe.AddShader(&fs);
2144
2145 pipe.AddVertexInputBindings(input_bindings, 2);
2146 pipe.AddVertexInputAttribs(&input_attrib, 1);
2147
2148 VkCommandBufferObj dummyCmd(m_device);
2149 VkDescriptorSetObj descriptorSet(m_device);
2150 descriptorSet.AppendDummy();
2151 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2152
2153 m_errorMonitor->ClearState();
2154 pipe.CreateVKPipeline(descriptorSet);
2155
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002156 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes280ba2c2015-06-12 11:16:41 +12002157
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002158 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes280ba2c2015-06-12 11:16:41 +12002159 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2160 FAIL() << "Incorrect error: " << msgString;
2161 }
2162}
Chris Forbes8f68b562015-05-25 11:13:32 +12002163
Chris Forbes4d6d1e52015-05-25 11:13:40 +12002164/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2165 * rejects it. */
2166
2167TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2168{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002169 VkFlags msgFlags;
Chris Forbes4d6d1e52015-05-25 11:13:40 +12002170 std::string msgString;
2171 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06002172 ScopedUseGlsl useGlsl(false);
Chris Forbes4d6d1e52015-05-25 11:13:40 +12002173
2174 char const *vsSource =
2175 "#version 140\n"
2176 "#extension GL_ARB_separate_shader_objects: require\n"
2177 "#extension GL_ARB_shading_language_420pack: require\n"
2178 "\n"
2179 "void main(){\n"
2180 " gl_Position = vec4(1);\n"
2181 "}\n";
2182 char const *fsSource =
2183 "#version 140\n"
2184 "#extension GL_ARB_separate_shader_objects: require\n"
2185 "#extension GL_ARB_shading_language_420pack: require\n"
2186 "\n"
2187 "void main(){\n"
2188 "}\n";
2189
2190 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2191 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2192
2193 VkPipelineObj pipe(m_device);
2194 pipe.AddShader(&vs);
2195 pipe.AddShader(&fs);
2196
2197 /* implicit CB 0 set up by the test framework, not written */
2198
2199 VkCommandBufferObj dummyCmd(m_device);
2200 VkDescriptorSetObj descriptorSet(m_device);
2201 descriptorSet.AppendDummy();
2202 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2203
2204 m_errorMonitor->ClearState();
2205 pipe.CreateVKPipeline(descriptorSet);
2206
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002207 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes4d6d1e52015-05-25 11:13:40 +12002208
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002209 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes4d6d1e52015-05-25 11:13:40 +12002210 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2211 FAIL() << "Incorrect error: " << msgString;
2212 }
2213}
2214
Chris Forbesf3fffaa2015-05-25 11:13:43 +12002215TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2216{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002217 VkFlags msgFlags;
Chris Forbesf3fffaa2015-05-25 11:13:43 +12002218 std::string msgString;
2219 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06002220 ScopedUseGlsl useGlsl(false);
Chris Forbesf3fffaa2015-05-25 11:13:43 +12002221
2222 char const *vsSource =
2223 "#version 140\n"
2224 "#extension GL_ARB_separate_shader_objects: require\n"
2225 "#extension GL_ARB_shading_language_420pack: require\n"
2226 "\n"
2227 "void main(){\n"
2228 " gl_Position = vec4(1);\n"
2229 "}\n";
2230 char const *fsSource =
2231 "#version 140\n"
2232 "#extension GL_ARB_separate_shader_objects: require\n"
2233 "#extension GL_ARB_shading_language_420pack: require\n"
2234 "\n"
2235 "layout(location=0) out vec4 x;\n"
2236 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2237 "void main(){\n"
2238 " x = vec4(1);\n"
2239 " y = vec4(1);\n"
2240 "}\n";
2241
2242 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2243 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2244
2245 VkPipelineObj pipe(m_device);
2246 pipe.AddShader(&vs);
2247 pipe.AddShader(&fs);
2248
2249 /* implicit CB 0 set up by the test framework */
2250 /* FS writes CB 1, but we don't configure it */
2251
2252 VkCommandBufferObj dummyCmd(m_device);
2253 VkDescriptorSetObj descriptorSet(m_device);
2254 descriptorSet.AppendDummy();
2255 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2256
2257 m_errorMonitor->ClearState();
2258 pipe.CreateVKPipeline(descriptorSet);
2259
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002260 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesf3fffaa2015-05-25 11:13:43 +12002261
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002262 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesf3fffaa2015-05-25 11:13:43 +12002263 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2264 FAIL() << "Incorrect warning: " << msgString;
2265 }
2266}
2267
Chris Forbesa36d69e2015-05-25 11:13:44 +12002268TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2269{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002270 VkFlags msgFlags;
Chris Forbesa36d69e2015-05-25 11:13:44 +12002271 std::string msgString;
2272 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop50a2a4b2015-06-03 16:49:20 -06002273 ScopedUseGlsl useGlsl(false);
Chris Forbesa36d69e2015-05-25 11:13:44 +12002274
2275 char const *vsSource =
2276 "#version 140\n"
2277 "#extension GL_ARB_separate_shader_objects: require\n"
2278 "#extension GL_ARB_shading_language_420pack: require\n"
2279 "\n"
2280 "void main(){\n"
2281 " gl_Position = vec4(1);\n"
2282 "}\n";
2283 char const *fsSource =
2284 "#version 140\n"
2285 "#extension GL_ARB_separate_shader_objects: require\n"
2286 "#extension GL_ARB_shading_language_420pack: require\n"
2287 "\n"
2288 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2289 "void main(){\n"
2290 " x = ivec4(1);\n"
2291 "}\n";
2292
2293 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2294 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2295
2296 VkPipelineObj pipe(m_device);
2297 pipe.AddShader(&vs);
2298 pipe.AddShader(&fs);
2299
2300 /* implicit CB 0 set up by test framework, is UNORM. */
2301
2302 VkCommandBufferObj dummyCmd(m_device);
2303 VkDescriptorSetObj descriptorSet(m_device);
2304 descriptorSet.AppendDummy();
2305 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2306
2307 m_errorMonitor->ClearState();
2308 pipe.CreateVKPipeline(descriptorSet);
2309
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002310 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa36d69e2015-05-25 11:13:44 +12002311
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002312 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa36d69e2015-05-25 11:13:44 +12002313 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2314 FAIL() << "Incorrect error: " << msgString;
2315 }
2316}
Chris Forbes7b1b8932015-06-05 14:43:36 +12002317
2318TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2319{
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002320 VkFlags msgFlags;
Chris Forbes7b1b8932015-06-05 14:43:36 +12002321 std::string msgString;
2322 ASSERT_NO_FATAL_FAILURE(InitState());
2323 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop50a2a4b2015-06-03 16:49:20 -06002324 ScopedUseGlsl useGlsl(true);
Chris Forbes7b1b8932015-06-05 14:43:36 +12002325
2326 char const *vsSource =
2327 "#version 140\n"
2328 "#extension GL_ARB_separate_shader_objects: require\n"
2329 "#extension GL_ARB_shading_language_420pack: require\n"
2330 "\n"
2331 "void main(){\n"
2332 " gl_Position = vec4(1);\n"
2333 "}\n";
2334 char const *fsSource =
2335 "#version 140\n"
2336 "#extension GL_ARB_separate_shader_objects: require\n"
2337 "#extension GL_ARB_shading_language_420pack: require\n"
2338 "\n"
2339 "layout(location=0) out vec4 x;\n"
2340 "void main(){\n"
2341 " x = vec4(1);\n"
2342 "}\n";
2343
2344 m_errorMonitor->ClearState();
2345
2346 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2347 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2348
2349
2350 VkPipelineObj pipe(m_device);
2351 pipe.AddShader(&vs);
2352 pipe.AddShader(&fs);
2353
2354 /* implicit CB 0 set up by test framework, is UNORM. */
2355
2356 VkCommandBufferObj dummyCmd(m_device);
2357 VkDescriptorSetObj descriptorSet(m_device);
2358 descriptorSet.AppendDummy();
2359 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2360
2361 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2362 /* pipeline creation should have succeeded */
2363 ASSERT_EQ(VK_SUCCESS, res);
2364
2365 /* should have emitted a warning: the shader is not SPIRV, so we're
2366 * not going to be able to analyze it */
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002367 msgFlags = m_errorMonitor->GetState(&msgString);
2368 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes7b1b8932015-06-05 14:43:36 +12002369 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2370 FAIL() << "Incorrect warning: " << msgString;
2371 }
2372}
Chris Forbesd9b20ca2015-06-04 09:25:25 +12002373#endif
Chris Forbesa36d69e2015-05-25 11:13:44 +12002374
Tony Barbour300a6082015-04-07 13:44:53 -06002375int main(int argc, char **argv) {
2376 int result;
2377
2378 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour6918cd52015-04-09 12:58:51 -06002379 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour300a6082015-04-07 13:44:53 -06002380
2381 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2382
2383 result = RUN_ALL_TESTS();
2384
Tony Barbour6918cd52015-04-09 12:58:51 -06002385 VkTestFramework::Finish();
Tony Barbour300a6082015-04-07 13:44:53 -06002386 return result;
2387}