blob: 34b6ebf30f90718de7049a88c4117191c5fb4745 [file] [log] [blame]
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001#include <vulkan.h>
2#include <vkDbg.h>
Tony Barbour30486ea2015-04-07 13:44:53 -06003#include "gtest-1.7.0/include/gtest/gtest.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06004#include "vkrenderframework.h"
Mark Lobodzinskia910dc82015-05-14 14:30:48 -05005#include "layers_config.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06006
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05007#define GLM_FORCE_RADIANS
8#include "glm/glm.hpp"
9#include <glm/gtc/matrix_transform.hpp>
10
Tobin Ehlis57e6a612015-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
15
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050016//--------------------------------------------------------------------------------------
17// Mesh and VertexFormat Data
18//--------------------------------------------------------------------------------------
19struct Vertex
20{
21 float posX, posY, posZ, posW; // Position data
22 float r, g, b, a; // Color
23};
24
25#define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
26
27typedef enum _BsoFailSelect {
28 BsoFailNone = 0x00000000,
29 BsoFailRaster = 0x00000001,
30 BsoFailViewport = 0x00000002,
31 BsoFailColorBlend = 0x00000004,
32 BsoFailDepthStencil = 0x00000008,
33} BsoFailSelect;
34
35struct vktriangle_vs_uniform {
36 // Must start with MVP
37 float mvp[4][4];
38 float position[3][4];
39 float color[3][4];
40};
41
42static const char *bindStateVertShaderText =
43 "#version 130\n"
44 "vec2 vertices[3];\n"
45 "void main() {\n"
46 " vertices[0] = vec2(-1.0, -1.0);\n"
47 " vertices[1] = vec2( 1.0, -1.0);\n"
48 " vertices[2] = vec2( 0.0, 1.0);\n"
49 " gl_Position = vec4(vertices[gl_VertexID % 3], 0.0, 1.0);\n"
50 "}\n";
51
52static const char *bindStateFragShaderText =
53 "#version 130\n"
54 "void main() {\n"
55 " gl_FragColor = vec4(0,1,0,1);\n"
56 "}\n";
57
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060058void VKAPI myDbgFunc(
59 VK_DBG_MSG_TYPE msgType,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060060 VkValidationLevel validationLevel,
Mike Stroyan230e6252015-04-17 12:36:38 -060061 VkObject srcObject,
Tony Barbour30486ea2015-04-07 13:44:53 -060062 size_t location,
63 int32_t msgCode,
64 const char* pMsg,
65 void* pUserData);
66
67class ErrorMonitor {
68public:
Tony Barbour0c1bdc62015-04-29 17:34:29 -060069 ErrorMonitor()
Tony Barbour30486ea2015-04-07 13:44:53 -060070 {
Mike Stroyan09aae812015-05-12 16:00:45 -060071 pthread_mutexattr_t attr;
72 pthread_mutexattr_init(&attr);
73 pthread_mutex_init(&m_mutex, &attr);
74 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060075 m_msgType = VK_DBG_MSG_UNKNOWN;
Mike Stroyan09aae812015-05-12 16:00:45 -060076 m_bailout = NULL;
77 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060078 }
79 void ClearState()
80 {
Mike Stroyan09aae812015-05-12 16:00:45 -060081 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060082 m_msgType = VK_DBG_MSG_UNKNOWN;
Tony Barbour30486ea2015-04-07 13:44:53 -060083 m_msgString.clear();
Mike Stroyan09aae812015-05-12 16:00:45 -060084 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060085 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060086 VK_DBG_MSG_TYPE GetState(std::string *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060087 {
Mike Stroyan09aae812015-05-12 16:00:45 -060088 pthread_mutex_lock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060089 *msgString = m_msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -060090 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060091 return m_msgType;
92 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060093 void SetState(VK_DBG_MSG_TYPE msgType, const char *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060094 {
Mike Stroyan09aae812015-05-12 16:00:45 -060095 pthread_mutex_lock(&m_mutex);
96 if (m_bailout != NULL) {
97 *m_bailout = true;
98 }
Tony Barbour30486ea2015-04-07 13:44:53 -060099 m_msgType = msgType;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600100 m_msgString.reserve(strlen(msgString));
101 m_msgString = msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -0600102 pthread_mutex_unlock(&m_mutex);
103 }
104 void SetBailout(bool *bailout)
105 {
106 m_bailout = bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600107 }
108
109private:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600110 VK_DBG_MSG_TYPE m_msgType;
Mike Stroyan09aae812015-05-12 16:00:45 -0600111 std::string m_msgString;
112 pthread_mutex_t m_mutex;
113 bool* m_bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600114};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500115
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600116void VKAPI myDbgFunc(
Mike Stroyan230e6252015-04-17 12:36:38 -0600117 VK_DBG_MSG_TYPE msgType,
118 VkValidationLevel validationLevel,
119 VkObject srcObject,
Tony Barbour30486ea2015-04-07 13:44:53 -0600120 size_t location,
121 int32_t msgCode,
122 const char* pMsg,
123 void* pUserData)
124{
Tony Barbour8508b8e2015-04-09 10:48:04 -0600125 if (msgType == VK_DBG_MSG_WARNING || msgType == VK_DBG_MSG_ERROR) {
126 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
127 errMonitor->SetState(msgType, pMsg);
128 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600129}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500130
Tony Barbour01999182015-04-09 12:58:51 -0600131class VkLayerTest : public VkRenderFramework
Tony Barbour30486ea2015-04-07 13:44:53 -0600132{
133public:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600134 VkResult BeginCommandBuffer(VkCommandBufferObj &cmdBuffer);
135 VkResult EndCommandBuffer(VkCommandBufferObj &cmdBuffer);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500136 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
137 void GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask);
Tony Barbour30486ea2015-04-07 13:44:53 -0600138
139protected:
Tony Barbour01999182015-04-09 12:58:51 -0600140 VkMemoryRefManager m_memoryRefManager;
141 ErrorMonitor *m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600142
143 virtual void SetUp() {
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600144 const char *extension_names[] = {"MemTracker", "ObjectTracker", "Threading", "DrawState"};
Mike Stroyan09aae812015-05-12 16:00:45 -0600145 const std::vector<const char *> extensions(extension_names,
146 extension_names + sizeof(extension_names)/sizeof(extension_names[0]));
Tony Barbour950ebc02015-04-23 12:55:36 -0600147
148 size_t extSize = sizeof(uint32_t);
149 uint32_t extCount = 0;
Tony Barbour04ada4a2015-04-23 15:28:27 -0600150 VkResult U_ASSERT_ONLY err;
Tony Barbour950ebc02015-04-23 12:55:36 -0600151 err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount);
152 assert(!err);
153
154 VkExtensionProperties extProp;
155 extSize = sizeof(VkExtensionProperties);
156 bool32_t extFound;
157
Tony Barbour04ada4a2015-04-23 15:28:27 -0600158 for (uint32_t i = 0; i < extensions.size(); i++) {
Tony Barbour950ebc02015-04-23 12:55:36 -0600159 extFound = 0;
160 for (uint32_t j = 0; j < extCount; j++) {
161 err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_PROPERTIES, j, &extSize, &extProp);
Tony Barbour04ada4a2015-04-23 15:28:27 -0600162 assert(!err);
163 if (!strcmp(extensions[i], extProp.extName)) {
Tony Barbour950ebc02015-04-23 12:55:36 -0600164 extFound = 1;
165 break;
166 }
167 }
Tony Barbour04ada4a2015-04-23 15:28:27 -0600168 ASSERT_EQ(extFound, 1) << "ERROR: Cannot find extension named " << extensions[i] << " which is necessary to pass this test";
Tony Barbour950ebc02015-04-23 12:55:36 -0600169 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600170
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500171 // Force layer output level to be >= WARNING so that we catch those messages but ignore others
172 setLayerOptionEnum("MemTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
173 setLayerOptionEnum("ObjectTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
174 setLayerOptionEnum("ThreadingReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600175 setLayerOptionEnum("DrawStateReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500176
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600177 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600178 this->app_info.pNext = NULL;
179 this->app_info.pAppName = "layer_tests";
180 this->app_info.appVersion = 1;
181 this->app_info.pEngineName = "unittest";
182 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600183 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600184
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600185 m_errorMonitor = new ErrorMonitor;
186 InitFramework(extensions, myDbgFunc, m_errorMonitor);
187
Tony Barbour30486ea2015-04-07 13:44:53 -0600188 }
189
190 virtual void TearDown() {
191 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600192 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600193 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600194 }
195};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500196
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600197VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600198{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600199 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600200
201 result = cmdBuffer.BeginCommandBuffer();
202
203 /*
204 * For render test all drawing happens in a single render pass
205 * on a single command buffer.
206 */
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600207 if (VK_SUCCESS == result) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600208 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
209 }
210
211 return result;
212}
213
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600214VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600215{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600216 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600217
218 cmdBuffer.EndRenderPass(renderPass());
219
220 result = cmdBuffer.EndCommandBuffer();
221
222 return result;
223}
224
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500225void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
226{
227 // Create identity matrix
228 int i;
229 struct vktriangle_vs_uniform data;
230
231 glm::mat4 Projection = glm::mat4(1.0f);
232 glm::mat4 View = glm::mat4(1.0f);
233 glm::mat4 Model = glm::mat4(1.0f);
234 glm::mat4 MVP = Projection * View * Model;
235 const int matrixSize = sizeof(MVP);
236 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
237
238 memcpy(&data.mvp, &MVP[0][0], matrixSize);
239
240 static const Vertex tri_data[] =
241 {
242 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
243 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
244 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
245 };
246
247 for (i=0; i<3; i++) {
248 data.position[i][0] = tri_data[i].posX;
249 data.position[i][1] = tri_data[i].posY;
250 data.position[i][2] = tri_data[i].posZ;
251 data.position[i][3] = tri_data[i].posW;
252 data.color[i][0] = tri_data[i].r;
253 data.color[i][1] = tri_data[i].g;
254 data.color[i][2] = tri_data[i].b;
255 data.color[i][3] = tri_data[i].a;
256 }
257
258 ASSERT_NO_FATAL_FAILURE(InitState());
259 ASSERT_NO_FATAL_FAILURE(InitViewport());
260
261 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
262
263 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
264 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
265
266 VkPipelineObj pipelineobj(m_device);
267 pipelineobj.AddShader(&vs);
268 pipelineobj.AddShader(&ps);
269
270 VkDescriptorSetObj descriptorSet(m_device);
271 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
272
273 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
274 VkCommandBufferObj cmdBuffer(m_device);
275 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
276
277 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
278
279 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
280
281 // render triangle
282 cmdBuffer.Draw(0, 3, 0, 1);
283
284 // finalize recording of the command buffer
285 EndCommandBuffer(cmdBuffer);
286
287 cmdBuffer.QueueCommandBuffer();
288}
289
290void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
291{
292 if (m_depthStencil->Initialized()) {
293 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
294 } else {
295 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
296 }
297
298 cmdBuffer->PrepareAttachments();
299 if ((failMask & BsoFailRaster) != BsoFailRaster) {
300 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
301 }
302 if ((failMask & BsoFailViewport) != BsoFailViewport) {
303 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
304 }
305 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
306 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
307 }
308 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
309 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
310 }
311 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
312 pipelineobj.CreateVKPipeline(descriptorSet);
313 cmdBuffer->BindPipeline(pipelineobj);
314 cmdBuffer->BindDescriptorSet(descriptorSet);
315}
316
317// ********************************************************************************************************************
318// ********************************************************************************************************************
319// ********************************************************************************************************************
320// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600321#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500322TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
323{
324 vk_testing::Fence testFence;
325 VK_DBG_MSG_TYPE msgType;
326 std::string msgString;
327
328 VkFenceCreateInfo fenceInfo = {};
329 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
330 fenceInfo.pNext = NULL;
331 fenceInfo.flags = 0;
332
333 ASSERT_NO_FATAL_FAILURE(InitState());
334 ASSERT_NO_FATAL_FAILURE(InitViewport());
335 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
336
337 VkCommandBufferObj cmdBuffer(m_device);
338 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
339
340 BeginCommandBuffer(cmdBuffer);
341 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
342 EndCommandBuffer(cmdBuffer);
343
344 testFence.init(*m_device, fenceInfo);
345
346 // Bypass framework since it does the waits automatically
347 VkResult err = VK_SUCCESS;
348 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
349 ASSERT_VK_SUCCESS( err );
350
351 m_errorMonitor->ClearState();
352 // Introduce failure by calling begin again before checking fence
353 vkResetCommandBuffer(cmdBuffer.obj());
354
355 msgType = m_errorMonitor->GetState(&msgString);
356 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
357 if (!strstr(msgString.c_str(),"Resetting CB")) {
358 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
359 }
360}
361
362TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
363{
364 vk_testing::Fence testFence;
365 VK_DBG_MSG_TYPE msgType;
366 std::string msgString;
367
368 VkFenceCreateInfo fenceInfo = {};
369 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
370 fenceInfo.pNext = NULL;
371 fenceInfo.flags = 0;
372
373 ASSERT_NO_FATAL_FAILURE(InitState());
374 ASSERT_NO_FATAL_FAILURE(InitViewport());
375 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
376
377 VkCommandBufferObj cmdBuffer(m_device);
378 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
379
380 BeginCommandBuffer(cmdBuffer);
381 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
382 EndCommandBuffer(cmdBuffer);
383
384 testFence.init(*m_device, fenceInfo);
385
386 // Bypass framework since it does the waits automatically
387 VkResult err = VK_SUCCESS;
388 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
389 ASSERT_VK_SUCCESS( err );
390
391 m_errorMonitor->ClearState();
392 // Introduce failure by calling begin again before checking fence
393 BeginCommandBuffer(cmdBuffer);
394
395 msgType = m_errorMonitor->GetState(&msgString);
396 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
397 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
398 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
399 }
400}
401
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500402TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
403{
404 VK_DBG_MSG_TYPE msgType;
405 std::string msgString;
406 VkResult err;
407
408 ASSERT_NO_FATAL_FAILURE(InitState());
409 m_errorMonitor->ClearState();
410
411 // Create an image, allocate memory, free it, and then try to bind it
412 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500413 VkDeviceMemory mem;
414 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500415
416 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
417 const int32_t tex_width = 32;
418 const int32_t tex_height = 32;
419 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500420
421 const VkImageCreateInfo image_create_info = {
422 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
423 .pNext = NULL,
424 .imageType = VK_IMAGE_TYPE_2D,
425 .format = tex_format,
426 .extent = { tex_width, tex_height, 1 },
427 .mipLevels = 1,
428 .arraySize = 1,
429 .samples = 1,
430 .tiling = VK_IMAGE_TILING_LINEAR,
431 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
432 .flags = 0,
433 };
434 VkMemoryAllocInfo mem_alloc = {
435 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
436 .pNext = NULL,
437 .allocationSize = 0,
438 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
439 .memProps = 0,
440 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
441 };
442
443 err = vkCreateImage(m_device->device(), &image_create_info, &image);
444 ASSERT_VK_SUCCESS(err);
445
446 err = vkGetObjectInfo(m_device->device(),
447 VK_OBJECT_TYPE_IMAGE,
448 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500449 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
450 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500451 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500452 ASSERT_VK_SUCCESS(err);
453
Mark Lobodzinski23182612015-05-29 09:32:35 -0500454 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500455
456 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500457 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500458 ASSERT_VK_SUCCESS(err);
459
460 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500461 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500462 ASSERT_VK_SUCCESS(err);
463
464 // Map memory as if to initialize the image
465 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500466 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500467
468 msgType = m_errorMonitor->GetState(&msgString);
469 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to map memory not visible to CPU";
470 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
471 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
472 }
473}
474
475TEST_F(VkLayerTest, BindInvalidMemory)
476{
477 VK_DBG_MSG_TYPE msgType;
478 std::string msgString;
479 VkResult err;
480
481 ASSERT_NO_FATAL_FAILURE(InitState());
482 m_errorMonitor->ClearState();
483
484 // Create an image, allocate memory, free it, and then try to bind it
485 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500486 VkDeviceMemory mem;
487 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500488
489 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
490 const int32_t tex_width = 32;
491 const int32_t tex_height = 32;
492 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500493
494 const VkImageCreateInfo image_create_info = {
495 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
496 .pNext = NULL,
497 .imageType = VK_IMAGE_TYPE_2D,
498 .format = tex_format,
499 .extent = { tex_width, tex_height, 1 },
500 .mipLevels = 1,
501 .arraySize = 1,
502 .samples = 1,
503 .tiling = VK_IMAGE_TILING_LINEAR,
504 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
505 .flags = 0,
506 };
507 VkMemoryAllocInfo mem_alloc = {
508 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
509 .pNext = NULL,
510 .allocationSize = 0,
511 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
512 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
513 };
514
515 err = vkCreateImage(m_device->device(), &image_create_info, &image);
516 ASSERT_VK_SUCCESS(err);
517
518 err = vkGetObjectInfo(m_device->device(),
519 VK_OBJECT_TYPE_IMAGE,
520 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500521 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
522 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500523 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500524 ASSERT_VK_SUCCESS(err);
525
Mark Lobodzinski23182612015-05-29 09:32:35 -0500526 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500527
528 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500529 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500530 ASSERT_VK_SUCCESS(err);
531
532 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500533 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500534 ASSERT_VK_SUCCESS(err);
535
536 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500537 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500538 ASSERT_VK_SUCCESS(err);
539
540 msgType = m_errorMonitor->GetState(&msgString);
541 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to bind a freed memory object";
542 if (!strstr(msgString.c_str(),"Unable to set object")) {
543 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
544 }
545}
546
547TEST_F(VkLayerTest, FreeBoundMemory)
548{
549 VK_DBG_MSG_TYPE msgType;
550 std::string msgString;
551 VkResult err;
552
553 ASSERT_NO_FATAL_FAILURE(InitState());
554 m_errorMonitor->ClearState();
555
556 // Create an image, allocate memory, free it, and then try to bind it
557 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500558 VkDeviceMemory mem;
559 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500560
561 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
562 const int32_t tex_width = 32;
563 const int32_t tex_height = 32;
564 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500565
566 const VkImageCreateInfo image_create_info = {
567 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
568 .pNext = NULL,
569 .imageType = VK_IMAGE_TYPE_2D,
570 .format = tex_format,
571 .extent = { tex_width, tex_height, 1 },
572 .mipLevels = 1,
573 .arraySize = 1,
574 .samples = 1,
575 .tiling = VK_IMAGE_TILING_LINEAR,
576 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
577 .flags = 0,
578 };
579 VkMemoryAllocInfo mem_alloc = {
580 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
581 .pNext = NULL,
582 .allocationSize = 0,
583 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
584 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
585 };
586
587 err = vkCreateImage(m_device->device(), &image_create_info, &image);
588 ASSERT_VK_SUCCESS(err);
589
590 err = vkGetObjectInfo(m_device->device(),
591 VK_OBJECT_TYPE_IMAGE,
592 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500593 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
594 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500595 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500596 ASSERT_VK_SUCCESS(err);
597
Mark Lobodzinski23182612015-05-29 09:32:35 -0500598 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500599
600 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500601 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500602 ASSERT_VK_SUCCESS(err);
603
604 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500605 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500606 ASSERT_VK_SUCCESS(err);
607
608 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500609 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500610 ASSERT_VK_SUCCESS(err);
611
612 msgType = m_errorMonitor->GetState(&msgString);
613 ASSERT_EQ(msgType, VK_DBG_MSG_WARNING) << "Did not receive an warning while tring to free bound memory";
614 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
615 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
616 }
617}
618
619
620TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
621{
622 VK_DBG_MSG_TYPE msgType;
623 std::string msgString;
624 VkResult err;
625
626 ASSERT_NO_FATAL_FAILURE(InitState());
627 m_errorMonitor->ClearState();
628
629 // Create an image object, allocate memory, destroy the object and then try to bind it
630 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500631 VkDeviceMemory mem;
632 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500633
634 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
635 const int32_t tex_width = 32;
636 const int32_t tex_height = 32;
637 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500638
639 const VkImageCreateInfo image_create_info = {
640 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
641 .pNext = NULL,
642 .imageType = VK_IMAGE_TYPE_2D,
643 .format = tex_format,
644 .extent = { tex_width, tex_height, 1 },
645 .mipLevels = 1,
646 .arraySize = 1,
647 .samples = 1,
648 .tiling = VK_IMAGE_TILING_LINEAR,
649 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
650 .flags = 0,
651 };
652 VkMemoryAllocInfo mem_alloc = {
653 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
654 .pNext = NULL,
655 .allocationSize = 0,
656 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
657 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
658 };
659
660 err = vkCreateImage(m_device->device(), &image_create_info, &image);
661 ASSERT_VK_SUCCESS(err);
662
663 err = vkGetObjectInfo(m_device->device(),
664 VK_OBJECT_TYPE_IMAGE,
665 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500666 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
667 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500668 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500669 ASSERT_VK_SUCCESS(err);
670
Mark Lobodzinski23182612015-05-29 09:32:35 -0500671 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500672
673 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500674 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500675 ASSERT_VK_SUCCESS(err);
676
677 // Introduce validation failure, destroy Image object before binding
678 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
679 ASSERT_VK_SUCCESS(err);
680
681 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500682 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500683 ASSERT_VK_SUCCESS(err);
684
685 msgType = m_errorMonitor->GetState(&msgString);
686 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while binding memory to a destroyed object";
687 if (!strstr(msgString.c_str(),"Unable to set object")) {
688 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
689 }
690}
691
Tony Barbour8508b8e2015-04-09 10:48:04 -0600692TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600693{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600694 vk_testing::Fence testFence;
695 VK_DBG_MSG_TYPE msgType;
Tony Barbour30486ea2015-04-07 13:44:53 -0600696 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600697
698 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600699 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
700 fenceInfo.pNext = NULL;
701 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600702
Tony Barbour30486ea2015-04-07 13:44:53 -0600703 ASSERT_NO_FATAL_FAILURE(InitState());
704 ASSERT_NO_FATAL_FAILURE(InitViewport());
705 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
706
Tony Barbour01999182015-04-09 12:58:51 -0600707 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600708 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
709
Tony Barbour8508b8e2015-04-09 10:48:04 -0600710 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600711 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600712 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600713
714 testFence.init(*m_device, fenceInfo);
715 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600716 cmdBuffer.QueueCommandBuffer(testFence.obj());
Tony Barbour30486ea2015-04-07 13:44:53 -0600717 msgType = m_errorMonitor->GetState(&msgString);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600718 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
719 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500720 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600721 }
722
723}
724
725TEST_F(VkLayerTest, ResetUnsignaledFence)
726{
727 vk_testing::Fence testFence;
728 VK_DBG_MSG_TYPE msgType;
729 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600730 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600731 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
732 fenceInfo.pNext = NULL;
733
Tony Barbour8508b8e2015-04-09 10:48:04 -0600734 ASSERT_NO_FATAL_FAILURE(InitState());
735 testFence.init(*m_device, fenceInfo);
736 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600737 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600738 vkResetFences(m_device->device(), 1, fences);
739 msgType = m_errorMonitor->GetState(&msgString);
740 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from submitting fence with UNSIGNALED state to vkResetFences";
Tony Barbour01999182015-04-09 12:58:51 -0600741 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500742 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600743 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600744
745}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600746#endif
747#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600748TEST_F(VkLayerTest, WaitForUnsubmittedFence)
749{
750 vk_testing::Fence testFence;
751 VK_DBG_MSG_TYPE msgType;
752 std::string msgString;
753 VkFenceCreateInfo fenceInfo = {};
754 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
755 fenceInfo.pNext = NULL;
756
Tony Barbour54cdd192015-04-22 15:12:07 -0600757 ASSERT_NO_FATAL_FAILURE(InitState());
758 testFence.init(*m_device, fenceInfo);
759 m_errorMonitor->ClearState();
760 vkGetFenceStatus(m_device->device(),testFence.obj());
761 msgType = m_errorMonitor->GetState(&msgString);
762 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error asking for status of unsubmitted fence";
763 if (!strstr(msgString.c_str(),"Status Requested for Unsubmitted Fence")) {
764 FAIL() << "Error received was not Status Requested for Unsubmitted Fence";
765 }
766
767 VkFence fences[1] = {testFence.obj()};
768 m_errorMonitor->ClearState();
769 vkWaitForFences(m_device->device(), 1, fences, VK_TRUE, 0);
770 msgType = m_errorMonitor->GetState(&msgString);
771 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error for waiting for unsubmitted fence";
772 if (!strstr(msgString.c_str(),"Waiting for Unsubmitted Fence")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500773 FAIL() << "Error received was not 'Waiting for Unsubmitted Fence'";
Tony Barbour54cdd192015-04-22 15:12:07 -0600774 }
775}
776
Tony Barbourdb686622015-05-06 09:35:56 -0600777TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
778{
779 VkEventCreateInfo event_info;
780 VkEvent event;
781 VkMemoryRequirements mem_req;
782 size_t data_size = sizeof(mem_req);
783 VK_DBG_MSG_TYPE msgType;
784 std::string msgString;
785 VkResult err;
786
787 ASSERT_NO_FATAL_FAILURE(InitState());
788 memset(&event_info, 0, sizeof(event_info));
789 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
790
791 err = vkCreateEvent(device(), &event_info, &event);
792 ASSERT_VK_SUCCESS(err);
793 m_errorMonitor->ClearState();
794 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
795 &data_size, &mem_req);
796 msgType = m_errorMonitor->GetState(&msgString);
797 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from mismatched types in vkGetObjectInfo";
798 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500799 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600800 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500801}
Tony Barbourdb686622015-05-06 09:35:56 -0600802
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500803TEST_F(VkLayerTest, RasterStateNotBound)
804{
805 VK_DBG_MSG_TYPE msgType;
806 std::string msgString;
807
808 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
809
810 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
811
812 msgType = m_errorMonitor->GetState(&msgString);
813 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
814 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
815 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
816 }
817}
818
819TEST_F(VkLayerTest, ViewportStateNotBound)
820{
821 VK_DBG_MSG_TYPE msgType;
822 std::string msgString;
823 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
824
825 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
826
827 msgType = m_errorMonitor->GetState(&msgString);
828 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
829 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
830 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
831 }
832}
833
834TEST_F(VkLayerTest, ColorBlendStateNotBound)
835{
836 VK_DBG_MSG_TYPE msgType;
837 std::string msgString;
838
839 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
840
841 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
842
843 msgType = m_errorMonitor->GetState(&msgString);
844 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
845 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
846 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
847 }
848}
849
850TEST_F(VkLayerTest, DepthStencilStateNotBound)
851{
852 VK_DBG_MSG_TYPE msgType;
853 std::string msgString;
854
855 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
856
857 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
858
859 msgType = m_errorMonitor->GetState(&msgString);
860 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
861 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
862 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
863 }
Tony Barbourdb686622015-05-06 09:35:56 -0600864}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600865#endif
866#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600867TEST_F(VkLayerTest, PipelineNotBound)
868{
869 // Initiate Draw w/o a PSO bound
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600870 VK_DBG_MSG_TYPE msgType;
871 std::string msgString;
872
873 ASSERT_NO_FATAL_FAILURE(InitState());
874 m_errorMonitor->ClearState();
875 VkCommandBufferObj cmdBuffer(m_device);
876 BeginCommandBuffer(cmdBuffer);
877 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
878 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
879 msgType = m_errorMonitor->GetState(&msgString);
880 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
881 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
882 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
883 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600884}
885
886TEST_F(VkLayerTest, InvalidDescriptorPool)
887{
888 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
889 // The DS check for this is after driver has been called to validate DS internal data struct
890 // Attempt to clear DS Pool with bad object
891/* VK_DBG_MSG_TYPE msgType;
892 std::string msgString;
893 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
894 vkResetDescriptorPool(device(), badPool);
895
896 msgType = m_errorMonitor->GetState(&msgString);
897 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
898 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
899 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
900 }*/
901}
902
903TEST_F(VkLayerTest, InvalidDescriptorSet)
904{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600905 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
906 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600907 // Create a valid cmd buffer
908 // call vkCmdBindDescriptorSets w/ false DS
909}
910
911TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
912{
913 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
914 // The DS check for this is after driver has been called to validate DS internal data struct
915}
916
917TEST_F(VkLayerTest, InvalidPipeline)
918{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600919 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
920 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600921 // Create a valid cmd buffer
922 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600923 VK_DBG_MSG_TYPE msgType;
924 std::string msgString;
925
926 ASSERT_NO_FATAL_FAILURE(InitState());
927 m_errorMonitor->ClearState();
928 VkCommandBufferObj cmdBuffer(m_device);
929 BeginCommandBuffer(cmdBuffer);
930 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
931 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
932 msgType = m_errorMonitor->GetState(&msgString);
933 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
934 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
935 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
936 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600937}
938
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600939TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600940{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600941 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
942 VK_DBG_MSG_TYPE msgType;
943 std::string msgString;
944 VkResult err;
945
946 ASSERT_NO_FATAL_FAILURE(InitState());
947 m_errorMonitor->ClearState();
948 VkCommandBufferObj cmdBuffer(m_device);
949 const VkDescriptorTypeCount ds_type_count = {
950 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
951 .count = 1,
952 };
953 const VkDescriptorPoolCreateInfo ds_pool_ci = {
954 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
955 .pNext = NULL,
956 .count = 1,
957 .pTypeCount = &ds_type_count,
958 };
959 VkDescriptorPool ds_pool;
960 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
961 ASSERT_VK_SUCCESS(err);
962 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
963
964 const VkDescriptorSetLayoutBinding dsl_binding = {
965 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +0800966 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600967 .stageFlags = VK_SHADER_STAGE_ALL,
968 .pImmutableSamplers = NULL,
969 };
970
971 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
972 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
973 .pNext = NULL,
974 .count = 1,
975 .pBinding = &dsl_binding,
976 };
977 VkDescriptorSetLayout ds_layout;
978 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
979 ASSERT_VK_SUCCESS(err);
980
981 VkDescriptorSet descriptorSet;
982 uint32_t ds_count = 0;
983 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
984 ASSERT_VK_SUCCESS(err);
985
986 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
987 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
988 .pNext = NULL,
989 .descriptorSetCount = 1,
990 .pSetLayouts = &ds_layout,
991 };
992
993 VkPipelineLayout pipeline_layout;
994 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
995 ASSERT_VK_SUCCESS(err);
996
997 size_t shader_len = strlen(bindStateVertShaderText);
998 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
999 void* pCode = malloc(codeSize);
1000
1001 /* try version 0 first: VkShaderStage followed by GLSL */
1002 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1003 ((uint32_t *) pCode)[1] = 0;
1004 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1005 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1006
1007 const VkShaderCreateInfo vs_ci = {
1008 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1009 .pNext = NULL,
1010 .codeSize = codeSize,
1011 .pCode = pCode,
1012 .flags = 0,
1013 };
1014 VkShader vs;
1015 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1016 ASSERT_VK_SUCCESS(err);
1017
1018 const VkPipelineShader vs_pipe_shader = {
1019 .stage = VK_SHADER_STAGE_VERTEX,
1020 .shader = vs,
1021 .linkConstBufferCount = 0,
1022 .pLinkConstBufferInfo = NULL,
1023 .pSpecializationInfo = NULL,
1024 };
1025 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1026 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1027 .pNext = NULL,
1028 .shader = vs_pipe_shader,
1029 };
1030 const VkGraphicsPipelineCreateInfo gp_ci = {
1031 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1032 .pNext = &pipe_vs_ci,
1033 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1034 .layout = pipeline_layout,
1035 };
1036
1037 VkPipeline pipeline;
1038 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1039 ASSERT_VK_SUCCESS(err);
1040
1041 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1042 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1043
1044 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1045 m_device->get_device_queue();
1046 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1047
1048 msgType = m_errorMonitor->GetState(&msgString);
1049 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1050 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1051 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1052 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001053}
1054
1055TEST_F(VkLayerTest, InvalidDynamicStateObject)
1056{
1057 // Create a valid cmd buffer
1058 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001059 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1060 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001061}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001062
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001063TEST_F(VkLayerTest, DSUpdateWithoutBegin)
1064{
1065 // Call vkUpdateDescriptors w/ valid DS, but before vkBeginDescriptorPoolUpdate
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001066 VK_DBG_MSG_TYPE msgType;
1067 std::string msgString;
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001068 VkResult err;
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001069
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001070 ASSERT_NO_FATAL_FAILURE(InitState());
1071 m_errorMonitor->ClearState();
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001072 //VkDescriptorSetObj descriptorSet(m_device);
1073 const VkDescriptorTypeCount ds_type_count = {
1074 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1075 .count = 1,
1076 };
1077 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1078 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1079 .pNext = NULL,
1080 .count = 1,
1081 .pTypeCount = &ds_type_count,
1082 };
1083 VkDescriptorPool ds_pool;
1084 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1085 ASSERT_VK_SUCCESS(err);
1086 const VkDescriptorSetLayoutBinding dsl_binding = {
1087 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001088 .arraySize = 1,
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001089 .stageFlags = VK_SHADER_STAGE_ALL,
1090 .pImmutableSamplers = NULL,
1091 };
1092
1093 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1094 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1095 .pNext = NULL,
1096 .count = 1,
1097 .pBinding = &dsl_binding,
1098 };
1099 VkDescriptorSetLayout ds_layout;
1100 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1101 ASSERT_VK_SUCCESS(err);
1102
1103 VkDescriptorSet descriptorSet;
1104 uint32_t ds_count = 0;
1105 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1106 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001107 // Should fail before we attempt update so don't care about update contents
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001108 vkUpdateDescriptors(m_device->device(), descriptorSet, 0, NULL);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001109 msgType = m_errorMonitor->GetState(&msgString);
1110 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptors w/o first calling vkBeginDescriptorPoolUpdate().";
1111 if (!strstr(msgString.c_str(),"You must call vkBeginDescriptorPoolUpdate() before ")) {
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001112 FAIL() << "Error received was not 'You must call vkBeginDescriptorPoolUpdate() before this call to vkUpdateDescriptors()!'";
1113 }
1114}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001115
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001116TEST_F(VkLayerTest, DSEndWithoutBegin)
1117{
1118 // With a valid pool & cmdBuffer, call vkEndDescriptorPoolUpdate
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001119 VK_DBG_MSG_TYPE msgType;
1120 std::string msgString;
1121 VkResult err;
1122
1123 ASSERT_NO_FATAL_FAILURE(InitState());
1124 m_errorMonitor->ClearState();
1125 VkCommandBufferObj cmdBuffer(m_device);
1126 const VkDescriptorTypeCount ds_type_count = {
1127 .type = VK_DESCRIPTOR_TYPE_SAMPLER,
1128 .count = 1,
1129 };
1130 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1131 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1132 .pNext = NULL,
1133 .count = 1,
1134 .pTypeCount = &ds_type_count,
1135 };
1136 VkDescriptorPool ds_pool;
1137 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1138 ASSERT_VK_SUCCESS(err);
1139 vkEndDescriptorPoolUpdate(m_device->device(), cmdBuffer.GetBufferHandle());
1140 msgType = m_errorMonitor->GetState(&msgString);
1141 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1142 if (!strstr(msgString.c_str(),"You must call vkBeginDescriptorPoolUpdate() before this call to vkEndDescriptorPoolUpdate()!")) {
1143 FAIL() << "Error received was not 'You must call vkBeginDescriptorPoolUpdate() before this call to vkEndDescriptorPoolUpdate()!'";
1144 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001145}
1146
1147TEST_F(VkLayerTest, DSBoundWithoutEnd)
1148{
1149 // With a valid pool and & cmdBuffer, do Begin/Update w/o End and then QueueSubmit
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001150 VK_DBG_MSG_TYPE msgType;
1151 std::string msgString;
1152 VkResult err;
1153
1154 ASSERT_NO_FATAL_FAILURE(InitState());
1155 m_errorMonitor->ClearState();
1156 VkCommandBufferObj cmdBuffer(m_device);
1157 const VkDescriptorTypeCount ds_type_count = {
1158 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1159 .count = 1,
1160 };
1161 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1162 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1163 .pNext = NULL,
1164 .count = 1,
1165 .pTypeCount = &ds_type_count,
1166 };
1167 VkDescriptorPool ds_pool;
1168 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1169 ASSERT_VK_SUCCESS(err);
1170 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1171
1172 const VkDescriptorSetLayoutBinding dsl_binding = {
1173 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001174 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001175 .stageFlags = VK_SHADER_STAGE_ALL,
1176 .pImmutableSamplers = NULL,
1177 };
1178
1179 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1180 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1181 .pNext = NULL,
1182 .count = 1,
1183 .pBinding = &dsl_binding,
1184 };
1185 VkDescriptorSetLayout ds_layout;
1186 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1187 ASSERT_VK_SUCCESS(err);
1188
1189 VkDescriptorSet descriptorSet;
1190 uint32_t ds_count = 0;
1191 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1192 ASSERT_VK_SUCCESS(err);
1193
1194 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1195 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1196 .pNext = NULL,
1197 .descriptorSetCount = 1,
1198 .pSetLayouts = &ds_layout,
1199 };
1200
1201 VkPipelineLayout pipeline_layout;
1202 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1203 ASSERT_VK_SUCCESS(err);
1204
1205 size_t shader_len = strlen(bindStateVertShaderText);
1206 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1207 void* pCode = malloc(codeSize);
1208
1209 /* try version 0 first: VkShaderStage followed by GLSL */
1210 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1211 ((uint32_t *) pCode)[1] = 0;
1212 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1213 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1214
1215 const VkShaderCreateInfo vs_ci = {
1216 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1217 .pNext = NULL,
1218 .codeSize = codeSize,
1219 .pCode = pCode,
1220 .flags = 0,
1221 };
1222 VkShader vs;
1223 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1224
1225 const VkPipelineShader vs_pipe_shader = {
1226 .stage = VK_SHADER_STAGE_VERTEX,
1227 .shader = vs,
1228 .linkConstBufferCount = 0,
1229 .pLinkConstBufferInfo = NULL,
1230 .pSpecializationInfo = NULL,
1231 };
1232 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1233 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1234 .pNext = NULL,
1235 .shader = vs_pipe_shader,
1236 };
1237 const VkGraphicsPipelineCreateInfo gp_ci = {
1238 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1239 .pNext = &pipe_vs_ci,
1240 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1241 .layout = pipeline_layout,
1242 };
1243
1244 VkPipeline pipeline;
1245 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1246 ASSERT_VK_SUCCESS(err);
1247
1248 err= cmdBuffer.BeginCommandBuffer();
1249 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001250
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001251 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1252 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1253 cmdBuffer.EndCommandBuffer();
1254
1255 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1256 m_device->get_device_queue();
1257 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1258
1259 msgType = m_errorMonitor->GetState(&msgString);
1260 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1261 if (!strstr(msgString.c_str(),"You must call vkEndDescriptorPoolUpdate() before this call to vkQueueSubmit()!")) {
1262 FAIL() << "Error received was not 'You must call vkEndDescriptorPoolUpdate() before this call to vkQueueSubmit()!'";
1263 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001264}
1265
1266TEST_F(VkLayerTest, VtxBufferBadIndex)
1267{
1268 // Bind VBO out-of-bounds for given PSO
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001269 VK_DBG_MSG_TYPE msgType;
1270 std::string msgString;
1271 VkResult err;
1272
1273 ASSERT_NO_FATAL_FAILURE(InitState());
1274 m_errorMonitor->ClearState();
1275 VkCommandBufferObj cmdBuffer(m_device);
1276 const VkDescriptorTypeCount ds_type_count = {
1277 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1278 .count = 1,
1279 };
1280 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1281 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1282 .pNext = NULL,
1283 .count = 1,
1284 .pTypeCount = &ds_type_count,
1285 };
1286 VkDescriptorPool ds_pool;
1287 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1288 ASSERT_VK_SUCCESS(err);
1289 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1290
1291 const VkDescriptorSetLayoutBinding dsl_binding = {
1292 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001293 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001294 .stageFlags = VK_SHADER_STAGE_ALL,
1295 .pImmutableSamplers = NULL,
1296 };
1297
1298 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1299 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1300 .pNext = NULL,
1301 .count = 1,
1302 .pBinding = &dsl_binding,
1303 };
1304 VkDescriptorSetLayout ds_layout;
1305 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1306 ASSERT_VK_SUCCESS(err);
1307
1308 VkDescriptorSet descriptorSet;
1309 uint32_t ds_count = 0;
1310 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1311 ASSERT_VK_SUCCESS(err);
1312
1313 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1314 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1315 .pNext = NULL,
1316 .descriptorSetCount = 1,
1317 .pSetLayouts = &ds_layout,
1318 };
1319
1320 VkPipelineLayout pipeline_layout;
1321 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1322 ASSERT_VK_SUCCESS(err);
1323
1324 size_t shader_len = strlen(bindStateVertShaderText);
1325 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1326 void* pCode = malloc(codeSize);
1327
1328 /* try version 0 first: VkShaderStage followed by GLSL */
1329 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1330 ((uint32_t *) pCode)[1] = 0;
1331 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1332 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1333
1334 const VkShaderCreateInfo vs_ci = {
1335 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1336 .pNext = NULL,
1337 .codeSize = codeSize,
1338 .pCode = pCode,
1339 .flags = 0,
1340 };
1341 VkShader vs;
1342 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1343
1344 const VkPipelineShader vs_pipe_shader = {
1345 .stage = VK_SHADER_STAGE_VERTEX,
1346 .shader = vs,
1347 .linkConstBufferCount = 0,
1348 .pLinkConstBufferInfo = NULL,
1349 .pSpecializationInfo = NULL,
1350 };
1351 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1352 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1353 .pNext = NULL,
1354 .shader = vs_pipe_shader,
1355 };
1356 const VkGraphicsPipelineCreateInfo gp_ci = {
1357 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1358 .pNext = &pipe_vs_ci,
1359 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1360 .layout = pipeline_layout,
1361 };
1362
1363 VkPipeline pipeline;
1364 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1365 ASSERT_VK_SUCCESS(err);
1366
1367 err= cmdBuffer.BeginCommandBuffer();
1368 ASSERT_VK_SUCCESS(err);
1369 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1370 // Should error before calling to driver so don't care about actual data
1371 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1372
1373 msgType = m_errorMonitor->GetState(&msgString);
1374 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
1375 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1376 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1377 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001378}
1379
1380TEST_F(VkLayerTest, DSTypeMismatch)
1381{
1382 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001383 VK_DBG_MSG_TYPE msgType;
1384 std::string msgString;
1385 VkResult err;
1386
1387 ASSERT_NO_FATAL_FAILURE(InitState());
1388 m_errorMonitor->ClearState();
1389 //VkDescriptorSetObj descriptorSet(m_device);
1390 const VkDescriptorTypeCount ds_type_count = {
1391 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1392 .count = 1,
1393 };
1394 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1395 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1396 .pNext = NULL,
1397 .count = 1,
1398 .pTypeCount = &ds_type_count,
1399 };
1400 VkDescriptorPool ds_pool;
1401 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1402 ASSERT_VK_SUCCESS(err);
1403 const VkDescriptorSetLayoutBinding dsl_binding = {
1404 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001405 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001406 .stageFlags = VK_SHADER_STAGE_ALL,
1407 .pImmutableSamplers = NULL,
1408 };
1409
1410 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1411 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1412 .pNext = NULL,
1413 .count = 1,
1414 .pBinding = &dsl_binding,
1415 };
1416 VkDescriptorSetLayout ds_layout;
1417 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1418 ASSERT_VK_SUCCESS(err);
1419
1420 VkDescriptorSet descriptorSet;
1421 uint32_t ds_count = 0;
1422 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1423 ASSERT_VK_SUCCESS(err);
1424 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1425
1426 const VkSamplerCreateInfo sampler_ci = {
1427 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1428 .pNext = NULL,
1429 .magFilter = VK_TEX_FILTER_NEAREST,
1430 .minFilter = VK_TEX_FILTER_NEAREST,
1431 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1432 .addressU = VK_TEX_ADDRESS_CLAMP,
1433 .addressV = VK_TEX_ADDRESS_CLAMP,
1434 .addressW = VK_TEX_ADDRESS_CLAMP,
1435 .mipLodBias = 1.0,
1436 .maxAnisotropy = 1,
1437 .compareOp = VK_COMPARE_OP_NEVER,
1438 .minLod = 1.0,
1439 .maxLod = 1.0,
1440 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1441 };
1442 VkSampler sampler;
1443 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1444 ASSERT_VK_SUCCESS(err);
1445
1446 VkUpdateSamplers *pSamplerUpdate = (VkUpdateSamplers*)malloc(sizeof(VkUpdateSamplers));
1447 // This is a mismatched type for the layout which expects BUFFER
1448 pSamplerUpdate->sType = VK_STRUCTURE_TYPE_UPDATE_SAMPLERS;
1449 pSamplerUpdate->pNext = NULL;
1450 pSamplerUpdate->binding = 0;
1451 pSamplerUpdate->arrayIndex = 0;
1452 pSamplerUpdate->count = 1;
1453 pSamplerUpdate->pSamplers = &sampler;
1454 const void** ppUpdate = (const void**)&pSamplerUpdate;
1455 vkUpdateDescriptors(m_device->device(), descriptorSet, 1, ppUpdate);
1456 msgType = m_errorMonitor->GetState(&msgString);
1457 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating BUFFER Descriptor w/ incorrect type of SAMPLER.";
1458 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_UPDATE_SAMPLERS does not match ")) {
1459 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_UPDATE_SAMPLERS does not match overlapping binding type!'";
1460 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001461}
1462
1463TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1464{
1465 // For overlapping Update, have arrayIndex exceed that of layout
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001466 VK_DBG_MSG_TYPE msgType;
1467 std::string msgString;
1468 VkResult err;
1469
1470 ASSERT_NO_FATAL_FAILURE(InitState());
1471 m_errorMonitor->ClearState();
1472 //VkDescriptorSetObj descriptorSet(m_device);
1473 const VkDescriptorTypeCount ds_type_count = {
1474 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1475 .count = 1,
1476 };
1477 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1478 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1479 .pNext = NULL,
1480 .count = 1,
1481 .pTypeCount = &ds_type_count,
1482 };
1483 VkDescriptorPool ds_pool;
1484 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1485 ASSERT_VK_SUCCESS(err);
1486 const VkDescriptorSetLayoutBinding dsl_binding = {
1487 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001488 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001489 .stageFlags = VK_SHADER_STAGE_ALL,
1490 .pImmutableSamplers = NULL,
1491 };
1492
1493 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1494 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1495 .pNext = NULL,
1496 .count = 1,
1497 .pBinding = &dsl_binding,
1498 };
1499 VkDescriptorSetLayout ds_layout;
1500 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1501 ASSERT_VK_SUCCESS(err);
1502
1503 VkDescriptorSet descriptorSet;
1504 uint32_t ds_count = 0;
1505 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1506 ASSERT_VK_SUCCESS(err);
1507 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1508
1509 const VkSamplerCreateInfo sampler_ci = {
1510 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1511 .pNext = NULL,
1512 .magFilter = VK_TEX_FILTER_NEAREST,
1513 .minFilter = VK_TEX_FILTER_NEAREST,
1514 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1515 .addressU = VK_TEX_ADDRESS_CLAMP,
1516 .addressV = VK_TEX_ADDRESS_CLAMP,
1517 .addressW = VK_TEX_ADDRESS_CLAMP,
1518 .mipLodBias = 1.0,
1519 .maxAnisotropy = 1,
1520 .compareOp = VK_COMPARE_OP_NEVER,
1521 .minLod = 1.0,
1522 .maxLod = 1.0,
1523 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1524 };
1525 VkSampler sampler;
1526 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1527 ASSERT_VK_SUCCESS(err);
1528 // This is the wrong type, but out of bounds will be flagged first
1529 VkUpdateSamplers *pSamplerUpdate = (VkUpdateSamplers*)malloc(sizeof(VkUpdateSamplers));
1530 pSamplerUpdate->sType = VK_STRUCTURE_TYPE_UPDATE_SAMPLERS;
1531 pSamplerUpdate->pNext = NULL;
1532 pSamplerUpdate->binding = 0;
1533 pSamplerUpdate->arrayIndex = 1; /* This index out of bounds for the update */
1534 pSamplerUpdate->count = 1;
1535 pSamplerUpdate->pSamplers = &sampler;
1536 const void** ppUpdate = (const void**)&pSamplerUpdate;
1537 vkUpdateDescriptors(m_device->device(), descriptorSet, 1, ppUpdate);
1538 msgType = m_errorMonitor->GetState(&msgString);
1539 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ index out of bounds.";
1540 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_UPDATE_SAMPLERS is out of bounds for matching binding")) {
1541 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_UPDATE_SAMPLERS is out of bounds for matching binding...'";
1542 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001543}
1544
1545TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1546{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001547 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
1548 VK_DBG_MSG_TYPE msgType;
1549 std::string msgString;
1550 VkResult err;
1551
1552 ASSERT_NO_FATAL_FAILURE(InitState());
1553 m_errorMonitor->ClearState();
1554 //VkDescriptorSetObj descriptorSet(m_device);
1555 const VkDescriptorTypeCount ds_type_count = {
1556 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1557 .count = 1,
1558 };
1559 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1560 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1561 .pNext = NULL,
1562 .count = 1,
1563 .pTypeCount = &ds_type_count,
1564 };
1565 VkDescriptorPool ds_pool;
1566 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1567 ASSERT_VK_SUCCESS(err);
1568 const VkDescriptorSetLayoutBinding dsl_binding = {
1569 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001570 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001571 .stageFlags = VK_SHADER_STAGE_ALL,
1572 .pImmutableSamplers = NULL,
1573 };
1574
1575 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1576 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1577 .pNext = NULL,
1578 .count = 1,
1579 .pBinding = &dsl_binding,
1580 };
1581 VkDescriptorSetLayout ds_layout;
1582 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1583 ASSERT_VK_SUCCESS(err);
1584
1585 VkDescriptorSet descriptorSet;
1586 uint32_t ds_count = 0;
1587 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1588 ASSERT_VK_SUCCESS(err);
1589 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1590
1591 const VkSamplerCreateInfo sampler_ci = {
1592 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1593 .pNext = NULL,
1594 .magFilter = VK_TEX_FILTER_NEAREST,
1595 .minFilter = VK_TEX_FILTER_NEAREST,
1596 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1597 .addressU = VK_TEX_ADDRESS_CLAMP,
1598 .addressV = VK_TEX_ADDRESS_CLAMP,
1599 .addressW = VK_TEX_ADDRESS_CLAMP,
1600 .mipLodBias = 1.0,
1601 .maxAnisotropy = 1,
1602 .compareOp = VK_COMPARE_OP_NEVER,
1603 .minLod = 1.0,
1604 .maxLod = 1.0,
1605 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1606 };
1607 VkSampler sampler;
1608 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1609 ASSERT_VK_SUCCESS(err);
1610 // This is the wrong type, but out of bounds will be flagged first
1611 VkUpdateSamplers *pSamplerUpdate = (VkUpdateSamplers*)malloc(sizeof(VkUpdateSamplers));
1612 pSamplerUpdate->sType = VK_STRUCTURE_TYPE_UPDATE_SAMPLERS;
1613 pSamplerUpdate->pNext = NULL;
1614 pSamplerUpdate->binding = 2; /* This binding too big for the update */
1615 pSamplerUpdate->arrayIndex = 0;
1616 pSamplerUpdate->count = 1;
1617 pSamplerUpdate->pSamplers = &sampler;
1618 const void** ppUpdate = (const void**)&pSamplerUpdate;
1619 vkUpdateDescriptors(m_device->device(), descriptorSet, 1, ppUpdate);
1620 msgType = m_errorMonitor->GetState(&msgString);
1621 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ count too large for layout.";
1622 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1623 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1624 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001625}
1626
1627TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1628{
1629 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001630 VK_DBG_MSG_TYPE msgType;
1631 std::string msgString;
1632 VkResult err;
1633
1634 ASSERT_NO_FATAL_FAILURE(InitState());
1635 m_errorMonitor->ClearState();
1636 //VkDescriptorSetObj descriptorSet(m_device);
1637 const VkDescriptorTypeCount ds_type_count = {
1638 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1639 .count = 1,
1640 };
1641 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1642 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1643 .pNext = NULL,
1644 .count = 1,
1645 .pTypeCount = &ds_type_count,
1646 };
1647 VkDescriptorPool ds_pool;
1648 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1649 ASSERT_VK_SUCCESS(err);
1650 const VkDescriptorSetLayoutBinding dsl_binding = {
1651 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001652 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001653 .stageFlags = VK_SHADER_STAGE_ALL,
1654 .pImmutableSamplers = NULL,
1655 };
1656
1657 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1658 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1659 .pNext = NULL,
1660 .count = 1,
1661 .pBinding = &dsl_binding,
1662 };
1663 VkDescriptorSetLayout ds_layout;
1664 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1665 ASSERT_VK_SUCCESS(err);
1666
1667 VkDescriptorSet descriptorSet;
1668 uint32_t ds_count = 0;
1669 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1670 ASSERT_VK_SUCCESS(err);
1671 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1672
1673 const VkSamplerCreateInfo sampler_ci = {
1674 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1675 .pNext = NULL,
1676 .magFilter = VK_TEX_FILTER_NEAREST,
1677 .minFilter = VK_TEX_FILTER_NEAREST,
1678 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1679 .addressU = VK_TEX_ADDRESS_CLAMP,
1680 .addressV = VK_TEX_ADDRESS_CLAMP,
1681 .addressW = VK_TEX_ADDRESS_CLAMP,
1682 .mipLodBias = 1.0,
1683 .maxAnisotropy = 1,
1684 .compareOp = VK_COMPARE_OP_NEVER,
1685 .minLod = 1.0,
1686 .maxLod = 1.0,
1687 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1688 };
1689 VkSampler sampler;
1690 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1691 ASSERT_VK_SUCCESS(err);
1692 // This is the wrong type, but out of bounds will be flagged first
1693 VkUpdateSamplers *pSamplerUpdate = (VkUpdateSamplers*)malloc(sizeof(VkUpdateSamplers));
1694 pSamplerUpdate->sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1695 pSamplerUpdate->pNext = NULL;
1696 pSamplerUpdate->binding = 0;
1697 pSamplerUpdate->arrayIndex = 0;
1698 pSamplerUpdate->count = 1;
1699 pSamplerUpdate->pSamplers = &sampler;
1700 const void** ppUpdate = (const void**)&pSamplerUpdate;
1701 vkUpdateDescriptors(m_device->device(), descriptorSet, 1, ppUpdate);
1702 msgType = m_errorMonitor->GetState(&msgString);
1703 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ invalid struct type.";
1704 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1705 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1706 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001707}
1708
1709TEST_F(VkLayerTest, NumSamplesMismatch)
1710{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001711 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1712 VK_DBG_MSG_TYPE msgType;
1713 std::string msgString;
1714 VkResult err;
1715
1716 ASSERT_NO_FATAL_FAILURE(InitState());
1717 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1718 m_errorMonitor->ClearState();
1719 VkCommandBufferObj cmdBuffer(m_device);
1720 const VkDescriptorTypeCount ds_type_count = {
1721 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1722 .count = 1,
1723 };
1724 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1725 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1726 .pNext = NULL,
1727 .count = 1,
1728 .pTypeCount = &ds_type_count,
1729 };
1730 VkDescriptorPool ds_pool;
1731 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1732 ASSERT_VK_SUCCESS(err);
1733 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1734
1735 const VkDescriptorSetLayoutBinding dsl_binding = {
1736 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001737 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001738 .stageFlags = VK_SHADER_STAGE_ALL,
1739 .pImmutableSamplers = NULL,
1740 };
1741
1742 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1743 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1744 .pNext = NULL,
1745 .count = 1,
1746 .pBinding = &dsl_binding,
1747 };
1748 VkDescriptorSetLayout ds_layout;
1749 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1750 ASSERT_VK_SUCCESS(err);
1751
1752 VkDescriptorSet descriptorSet;
1753 uint32_t ds_count = 0;
1754 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1755 ASSERT_VK_SUCCESS(err);
1756
1757 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1758 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1759 .pNext = NULL,
1760 .samples = 1,
1761 .multisampleEnable = 1,
1762 .sampleShadingEnable = 0,
1763 .minSampleShading = 1.0,
1764 .sampleMask = 15,
1765 };
1766
1767 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1768 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1769 .pNext = NULL,
1770 .descriptorSetCount = 1,
1771 .pSetLayouts = &ds_layout,
1772 };
1773
1774 VkPipelineLayout pipeline_layout;
1775 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1776 ASSERT_VK_SUCCESS(err);
1777
1778 size_t shader_len = strlen(bindStateVertShaderText);
1779 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1780 void* pCode = malloc(codeSize);
1781
1782 /* try version 0 first: VkShaderStage followed by GLSL */
1783 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1784 ((uint32_t *) pCode)[1] = 0;
1785 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1786 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1787
1788 const VkShaderCreateInfo vs_ci = {
1789 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1790 .pNext = NULL,
1791 .codeSize = codeSize,
1792 .pCode = pCode,
1793 .flags = 0,
1794 };
1795 VkShader vs;
1796 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1797 ASSERT_VK_SUCCESS(err);
1798
1799 const VkPipelineShader vs_pipe_shader = {
1800 .stage = VK_SHADER_STAGE_VERTEX,
1801 .shader = vs,
1802 .linkConstBufferCount = 0,
1803 .pLinkConstBufferInfo = NULL,
1804 .pSpecializationInfo = NULL,
1805 };
1806 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1807 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1808 .pNext = &pipe_ms_state_ci,
1809 .shader = vs_pipe_shader,
1810 };
1811 const VkGraphicsPipelineCreateInfo gp_ci = {
1812 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1813 .pNext = &pipe_vs_ci,
1814 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1815 .layout = pipeline_layout,
1816 };
1817
1818 VkPipeline pipeline;
1819 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1820 ASSERT_VK_SUCCESS(err);
1821
1822 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1823 BeginCommandBuffer(cmdBuffer);
1824 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1825
1826 msgType = m_errorMonitor->GetState(&msgString);
1827 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
1828 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1829 FAIL() << "Error received was not 'Num samples mismatch!...'";
1830 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001831}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001832#endif
1833#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001834#if GTEST_IS_THREADSAFE
1835struct thread_data_struct {
1836 VkCmdBuffer cmdBuffer;
1837 VkEvent event;
1838 bool bailout;
1839};
1840
1841extern "C" void *AddToCommandBuffer(void *arg)
1842{
1843 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1844 std::string msgString;
1845
1846 for (int i = 0; i<10000; i++) {
1847 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1848 if (data->bailout) {
1849 break;
1850 }
1851 }
1852 return NULL;
1853}
1854
1855TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1856{
1857 VK_DBG_MSG_TYPE msgType;
1858 std::string msgString;
1859 pthread_t thread;
1860 pthread_attr_t thread_attr;
1861
1862 ASSERT_NO_FATAL_FAILURE(InitState());
1863 ASSERT_NO_FATAL_FAILURE(InitViewport());
1864 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1865
1866 VkCommandBufferObj cmdBuffer(m_device);
1867
1868 m_errorMonitor->ClearState();
1869 pthread_attr_init(&thread_attr);
1870 BeginCommandBuffer(cmdBuffer);
1871
1872 VkEventCreateInfo event_info;
1873 VkEvent event;
1874 VkMemoryRequirements mem_req;
1875 size_t data_size = sizeof(mem_req);
1876 VkResult err;
1877
1878 memset(&event_info, 0, sizeof(event_info));
1879 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1880
1881 err = vkCreateEvent(device(), &event_info, &event);
1882 ASSERT_VK_SUCCESS(err);
1883
1884 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1885 &data_size, &mem_req);
1886 ASSERT_VK_SUCCESS(err);
1887
1888 VkMemoryAllocInfo mem_info;
1889 VkDeviceMemory event_mem;
1890
1891 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1892
1893 memset(&mem_info, 0, sizeof(mem_info));
1894 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1895 mem_info.allocationSize = mem_req.size;
1896 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1897 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1898 err = vkAllocMemory(device(), &mem_info, &event_mem);
1899 ASSERT_VK_SUCCESS(err);
1900
Mark Lobodzinski23182612015-05-29 09:32:35 -05001901 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001902 ASSERT_VK_SUCCESS(err);
1903
1904 err = vkResetEvent(device(), event);
1905 ASSERT_VK_SUCCESS(err);
1906
1907 struct thread_data_struct data;
1908 data.cmdBuffer = cmdBuffer.obj();
1909 data.event = event;
1910 data.bailout = false;
1911 m_errorMonitor->SetBailout(&data.bailout);
1912 // Add many entries to command buffer from another thread.
1913 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1914 // Add many entries to command buffer from this thread at the same time.
1915 AddToCommandBuffer(&data);
1916 pthread_join(thread, NULL);
1917 EndCommandBuffer(cmdBuffer);
1918
1919 msgType = m_errorMonitor->GetState(&msgString);
1920 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using one VkCommandBufferObj in two threads";
1921 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001922 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001923 }
1924
1925}
1926#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001927#endif
Tony Barbour30486ea2015-04-07 13:44:53 -06001928int main(int argc, char **argv) {
1929 int result;
1930
1931 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06001932 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06001933
1934 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
1935
1936 result = RUN_ALL_TESTS();
1937
Tony Barbour01999182015-04-09 12:58:51 -06001938 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06001939 return result;
1940}