blob: 9be440f32cc2867dda9e7c3712bfd3d4b7bb3e5a [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;
413 VkDeviceMemory *mem;
414 VkMemoryRequirements *mem_reqs;
415
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);
420 uint32_t num_allocations = 0;
421 size_t num_alloc_size = sizeof(num_allocations);
422
423 const VkImageCreateInfo image_create_info = {
424 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
425 .pNext = NULL,
426 .imageType = VK_IMAGE_TYPE_2D,
427 .format = tex_format,
428 .extent = { tex_width, tex_height, 1 },
429 .mipLevels = 1,
430 .arraySize = 1,
431 .samples = 1,
432 .tiling = VK_IMAGE_TILING_LINEAR,
433 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
434 .flags = 0,
435 };
436 VkMemoryAllocInfo mem_alloc = {
437 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
438 .pNext = NULL,
439 .allocationSize = 0,
440 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
441 .memProps = 0,
442 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
443 };
444
445 err = vkCreateImage(m_device->device(), &image_create_info, &image);
446 ASSERT_VK_SUCCESS(err);
447
448 err = vkGetObjectInfo(m_device->device(),
449 VK_OBJECT_TYPE_IMAGE,
450 image,
451 VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT,
452 &num_alloc_size,
453 &num_allocations);
454 ASSERT_VK_SUCCESS(err);
455
456 mem_reqs = new VkMemoryRequirements[num_allocations];
457 mem = new VkDeviceMemory[num_allocations];
458
459 err = vkGetObjectInfo(m_device->device(),
460 VK_OBJECT_TYPE_IMAGE,
461 image,
462 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
463 &mem_reqs_size,
464 mem_reqs);
465 ASSERT_VK_SUCCESS(err);
466
467 mem_alloc.allocationSize = mem_reqs[0].size;
468
469 // allocate memory
470 err = vkAllocMemory(m_device->device(), &mem_alloc, &(mem[0]));
471 ASSERT_VK_SUCCESS(err);
472
473 // Try to bind free memory that has been freed
474 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, 0, mem[0], 0);
475 ASSERT_VK_SUCCESS(err);
476
477 // Map memory as if to initialize the image
478 void *mappedAddress = NULL;
479 err = vkMapMemory(m_device->device(), mem[0], 0, 0, 0, &mappedAddress);
480
481 msgType = m_errorMonitor->GetState(&msgString);
482 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to map memory not visible to CPU";
483 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
484 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
485 }
486}
487
488TEST_F(VkLayerTest, BindInvalidMemory)
489{
490 VK_DBG_MSG_TYPE msgType;
491 std::string msgString;
492 VkResult err;
493
494 ASSERT_NO_FATAL_FAILURE(InitState());
495 m_errorMonitor->ClearState();
496
497 // Create an image, allocate memory, free it, and then try to bind it
498 VkImage image;
499 VkDeviceMemory *mem;
500 VkMemoryRequirements *mem_reqs;
501
502 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
503 const int32_t tex_width = 32;
504 const int32_t tex_height = 32;
505 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
506 uint32_t num_allocations = 0;
507 size_t num_alloc_size = sizeof(num_allocations);
508
509 const VkImageCreateInfo image_create_info = {
510 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
511 .pNext = NULL,
512 .imageType = VK_IMAGE_TYPE_2D,
513 .format = tex_format,
514 .extent = { tex_width, tex_height, 1 },
515 .mipLevels = 1,
516 .arraySize = 1,
517 .samples = 1,
518 .tiling = VK_IMAGE_TILING_LINEAR,
519 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
520 .flags = 0,
521 };
522 VkMemoryAllocInfo mem_alloc = {
523 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
524 .pNext = NULL,
525 .allocationSize = 0,
526 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
527 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
528 };
529
530 err = vkCreateImage(m_device->device(), &image_create_info, &image);
531 ASSERT_VK_SUCCESS(err);
532
533 err = vkGetObjectInfo(m_device->device(),
534 VK_OBJECT_TYPE_IMAGE,
535 image,
536 VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT,
537 &num_alloc_size,
538 &num_allocations);
539 ASSERT_VK_SUCCESS(err);
540
541 mem_reqs = new VkMemoryRequirements[num_allocations];
542 mem = new VkDeviceMemory[num_allocations];
543
544 err = vkGetObjectInfo(m_device->device(),
545 VK_OBJECT_TYPE_IMAGE,
546 image,
547 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
548 &mem_reqs_size,
549 mem_reqs);
550 ASSERT_VK_SUCCESS(err);
551
552 mem_alloc.allocationSize = mem_reqs[0].size;
553
554 // allocate memory
555 err = vkAllocMemory(m_device->device(), &mem_alloc, &(mem[0]));
556 ASSERT_VK_SUCCESS(err);
557
558 // Introduce validation failure, free memory before binding
559 vkFreeMemory(m_device->device(), mem[0]);
560 ASSERT_VK_SUCCESS(err);
561
562 // Try to bind free memory that has been freed
563 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, 0, mem[0], 0);
564 ASSERT_VK_SUCCESS(err);
565
566 msgType = m_errorMonitor->GetState(&msgString);
567 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to bind a freed memory object";
568 if (!strstr(msgString.c_str(),"Unable to set object")) {
569 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
570 }
571}
572
573TEST_F(VkLayerTest, FreeBoundMemory)
574{
575 VK_DBG_MSG_TYPE msgType;
576 std::string msgString;
577 VkResult err;
578
579 ASSERT_NO_FATAL_FAILURE(InitState());
580 m_errorMonitor->ClearState();
581
582 // Create an image, allocate memory, free it, and then try to bind it
583 VkImage image;
584 VkDeviceMemory *mem;
585 VkMemoryRequirements *mem_reqs;
586
587 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
588 const int32_t tex_width = 32;
589 const int32_t tex_height = 32;
590 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
591 uint32_t num_allocations = 0;
592 size_t num_alloc_size = sizeof(num_allocations);
593
594 const VkImageCreateInfo image_create_info = {
595 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
596 .pNext = NULL,
597 .imageType = VK_IMAGE_TYPE_2D,
598 .format = tex_format,
599 .extent = { tex_width, tex_height, 1 },
600 .mipLevels = 1,
601 .arraySize = 1,
602 .samples = 1,
603 .tiling = VK_IMAGE_TILING_LINEAR,
604 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
605 .flags = 0,
606 };
607 VkMemoryAllocInfo mem_alloc = {
608 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
609 .pNext = NULL,
610 .allocationSize = 0,
611 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
612 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
613 };
614
615 err = vkCreateImage(m_device->device(), &image_create_info, &image);
616 ASSERT_VK_SUCCESS(err);
617
618 err = vkGetObjectInfo(m_device->device(),
619 VK_OBJECT_TYPE_IMAGE,
620 image,
621 VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT,
622 &num_alloc_size,
623 &num_allocations);
624 ASSERT_VK_SUCCESS(err);
625
626 mem_reqs = new VkMemoryRequirements[num_allocations];
627 mem = new VkDeviceMemory[num_allocations];
628
629 err = vkGetObjectInfo(m_device->device(),
630 VK_OBJECT_TYPE_IMAGE,
631 image,
632 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
633 &mem_reqs_size,
634 mem_reqs);
635 ASSERT_VK_SUCCESS(err);
636
637 mem_alloc.allocationSize = mem_reqs[0].size;
638
639 // allocate memory
640 err = vkAllocMemory(m_device->device(), &mem_alloc, &(mem[0]));
641 ASSERT_VK_SUCCESS(err);
642
643 // Bind memory to Image object
644 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, 0, mem[0], 0);
645 ASSERT_VK_SUCCESS(err);
646
647 // Introduce validation failure, free memory while still bound to object
648 vkFreeMemory(m_device->device(), mem[0]);
649 ASSERT_VK_SUCCESS(err);
650
651 msgType = m_errorMonitor->GetState(&msgString);
652 ASSERT_EQ(msgType, VK_DBG_MSG_WARNING) << "Did not receive an warning while tring to free bound memory";
653 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
654 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
655 }
656}
657
658
659TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
660{
661 VK_DBG_MSG_TYPE msgType;
662 std::string msgString;
663 VkResult err;
664
665 ASSERT_NO_FATAL_FAILURE(InitState());
666 m_errorMonitor->ClearState();
667
668 // Create an image object, allocate memory, destroy the object and then try to bind it
669 VkImage image;
670 VkDeviceMemory *mem;
671 VkMemoryRequirements *mem_reqs;
672
673 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
674 const int32_t tex_width = 32;
675 const int32_t tex_height = 32;
676 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
677 uint32_t num_allocations = 0;
678 size_t num_alloc_size = sizeof(num_allocations);
679
680 const VkImageCreateInfo image_create_info = {
681 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
682 .pNext = NULL,
683 .imageType = VK_IMAGE_TYPE_2D,
684 .format = tex_format,
685 .extent = { tex_width, tex_height, 1 },
686 .mipLevels = 1,
687 .arraySize = 1,
688 .samples = 1,
689 .tiling = VK_IMAGE_TILING_LINEAR,
690 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
691 .flags = 0,
692 };
693 VkMemoryAllocInfo mem_alloc = {
694 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
695 .pNext = NULL,
696 .allocationSize = 0,
697 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
698 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
699 };
700
701 err = vkCreateImage(m_device->device(), &image_create_info, &image);
702 ASSERT_VK_SUCCESS(err);
703
704 err = vkGetObjectInfo(m_device->device(),
705 VK_OBJECT_TYPE_IMAGE,
706 image,
707 VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT,
708 &num_alloc_size,
709 &num_allocations);
710 ASSERT_VK_SUCCESS(err);
711
712 mem_reqs = new VkMemoryRequirements[num_allocations];
713 mem = new VkDeviceMemory[num_allocations];
714
715 err = vkGetObjectInfo(m_device->device(),
716 VK_OBJECT_TYPE_IMAGE,
717 image,
718 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
719 &mem_reqs_size,
720 mem_reqs);
721 ASSERT_VK_SUCCESS(err);
722
723 mem_alloc.allocationSize = mem_reqs[0].size;
724
725 // Allocate memory
726 err = vkAllocMemory(m_device->device(), &mem_alloc, &(mem[0]));
727 ASSERT_VK_SUCCESS(err);
728
729 // Introduce validation failure, destroy Image object before binding
730 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
731 ASSERT_VK_SUCCESS(err);
732
733 // Now Try to bind memory to this destroyted object
734 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, 0, mem[0], 0);
735 ASSERT_VK_SUCCESS(err);
736
737 msgType = m_errorMonitor->GetState(&msgString);
738 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while binding memory to a destroyed object";
739 if (!strstr(msgString.c_str(),"Unable to set object")) {
740 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
741 }
742}
743
Tony Barbour8508b8e2015-04-09 10:48:04 -0600744TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600745{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600746 vk_testing::Fence testFence;
747 VK_DBG_MSG_TYPE msgType;
Tony Barbour30486ea2015-04-07 13:44:53 -0600748 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600749
750 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600751 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
752 fenceInfo.pNext = NULL;
753 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600754
Tony Barbour30486ea2015-04-07 13:44:53 -0600755 ASSERT_NO_FATAL_FAILURE(InitState());
756 ASSERT_NO_FATAL_FAILURE(InitViewport());
757 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
758
Tony Barbour01999182015-04-09 12:58:51 -0600759 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600760 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
761
Tony Barbour8508b8e2015-04-09 10:48:04 -0600762 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600763 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600764 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600765
766 testFence.init(*m_device, fenceInfo);
767 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600768 cmdBuffer.QueueCommandBuffer(testFence.obj());
Tony Barbour30486ea2015-04-07 13:44:53 -0600769 msgType = m_errorMonitor->GetState(&msgString);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600770 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
771 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500772 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600773 }
774
775}
776
777TEST_F(VkLayerTest, ResetUnsignaledFence)
778{
779 vk_testing::Fence testFence;
780 VK_DBG_MSG_TYPE msgType;
781 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600782 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600783 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
784 fenceInfo.pNext = NULL;
785
Tony Barbour8508b8e2015-04-09 10:48:04 -0600786 ASSERT_NO_FATAL_FAILURE(InitState());
787 testFence.init(*m_device, fenceInfo);
788 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600789 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600790 vkResetFences(m_device->device(), 1, fences);
791 msgType = m_errorMonitor->GetState(&msgString);
792 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 -0600793 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500794 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600795 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600796
797}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600798#endif
799#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600800TEST_F(VkLayerTest, WaitForUnsubmittedFence)
801{
802 vk_testing::Fence testFence;
803 VK_DBG_MSG_TYPE msgType;
804 std::string msgString;
805 VkFenceCreateInfo fenceInfo = {};
806 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
807 fenceInfo.pNext = NULL;
808
Tony Barbour54cdd192015-04-22 15:12:07 -0600809 ASSERT_NO_FATAL_FAILURE(InitState());
810 testFence.init(*m_device, fenceInfo);
811 m_errorMonitor->ClearState();
812 vkGetFenceStatus(m_device->device(),testFence.obj());
813 msgType = m_errorMonitor->GetState(&msgString);
814 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error asking for status of unsubmitted fence";
815 if (!strstr(msgString.c_str(),"Status Requested for Unsubmitted Fence")) {
816 FAIL() << "Error received was not Status Requested for Unsubmitted Fence";
817 }
818
819 VkFence fences[1] = {testFence.obj()};
820 m_errorMonitor->ClearState();
821 vkWaitForFences(m_device->device(), 1, fences, VK_TRUE, 0);
822 msgType = m_errorMonitor->GetState(&msgString);
823 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error for waiting for unsubmitted fence";
824 if (!strstr(msgString.c_str(),"Waiting for Unsubmitted Fence")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500825 FAIL() << "Error received was not 'Waiting for Unsubmitted Fence'";
Tony Barbour54cdd192015-04-22 15:12:07 -0600826 }
827}
828
Tony Barbourdb686622015-05-06 09:35:56 -0600829TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
830{
831 VkEventCreateInfo event_info;
832 VkEvent event;
833 VkMemoryRequirements mem_req;
834 size_t data_size = sizeof(mem_req);
835 VK_DBG_MSG_TYPE msgType;
836 std::string msgString;
837 VkResult err;
838
839 ASSERT_NO_FATAL_FAILURE(InitState());
840 memset(&event_info, 0, sizeof(event_info));
841 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
842
843 err = vkCreateEvent(device(), &event_info, &event);
844 ASSERT_VK_SUCCESS(err);
845 m_errorMonitor->ClearState();
846 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
847 &data_size, &mem_req);
848 msgType = m_errorMonitor->GetState(&msgString);
849 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from mismatched types in vkGetObjectInfo";
850 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500851 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600852 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500853}
Tony Barbourdb686622015-05-06 09:35:56 -0600854
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500855TEST_F(VkLayerTest, RasterStateNotBound)
856{
857 VK_DBG_MSG_TYPE msgType;
858 std::string msgString;
859
860 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
861
862 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
863
864 msgType = m_errorMonitor->GetState(&msgString);
865 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
866 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
867 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
868 }
869}
870
871TEST_F(VkLayerTest, ViewportStateNotBound)
872{
873 VK_DBG_MSG_TYPE msgType;
874 std::string msgString;
875 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
876
877 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
878
879 msgType = m_errorMonitor->GetState(&msgString);
880 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
881 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
882 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
883 }
884}
885
886TEST_F(VkLayerTest, ColorBlendStateNotBound)
887{
888 VK_DBG_MSG_TYPE msgType;
889 std::string msgString;
890
891 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
892
893 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
894
895 msgType = m_errorMonitor->GetState(&msgString);
896 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
897 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
898 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
899 }
900}
901
902TEST_F(VkLayerTest, DepthStencilStateNotBound)
903{
904 VK_DBG_MSG_TYPE msgType;
905 std::string msgString;
906
907 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
908
909 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
910
911 msgType = m_errorMonitor->GetState(&msgString);
912 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
913 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
914 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
915 }
Tony Barbourdb686622015-05-06 09:35:56 -0600916}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600917#endif
918#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600919TEST_F(VkLayerTest, PipelineNotBound)
920{
921 // Initiate Draw w/o a PSO bound
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600922 VK_DBG_MSG_TYPE msgType;
923 std::string msgString;
924
925 ASSERT_NO_FATAL_FAILURE(InitState());
926 m_errorMonitor->ClearState();
927 VkCommandBufferObj cmdBuffer(m_device);
928 BeginCommandBuffer(cmdBuffer);
929 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
930 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
931 msgType = m_errorMonitor->GetState(&msgString);
932 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
933 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
934 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
935 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600936}
937
938TEST_F(VkLayerTest, InvalidDescriptorPool)
939{
940 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
941 // The DS check for this is after driver has been called to validate DS internal data struct
942 // Attempt to clear DS Pool with bad object
943/* VK_DBG_MSG_TYPE msgType;
944 std::string msgString;
945 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
946 vkResetDescriptorPool(device(), badPool);
947
948 msgType = m_errorMonitor->GetState(&msgString);
949 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
950 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
951 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
952 }*/
953}
954
955TEST_F(VkLayerTest, InvalidDescriptorSet)
956{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600957 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
958 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600959 // Create a valid cmd buffer
960 // call vkCmdBindDescriptorSets w/ false DS
961}
962
963TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
964{
965 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
966 // The DS check for this is after driver has been called to validate DS internal data struct
967}
968
969TEST_F(VkLayerTest, InvalidPipeline)
970{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600971 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
972 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600973 // Create a valid cmd buffer
974 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600975 VK_DBG_MSG_TYPE msgType;
976 std::string msgString;
977
978 ASSERT_NO_FATAL_FAILURE(InitState());
979 m_errorMonitor->ClearState();
980 VkCommandBufferObj cmdBuffer(m_device);
981 BeginCommandBuffer(cmdBuffer);
982 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
983 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
984 msgType = m_errorMonitor->GetState(&msgString);
985 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
986 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
987 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
988 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600989}
990
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600991TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600992{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600993 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
994 VK_DBG_MSG_TYPE msgType;
995 std::string msgString;
996 VkResult err;
997
998 ASSERT_NO_FATAL_FAILURE(InitState());
999 m_errorMonitor->ClearState();
1000 VkCommandBufferObj cmdBuffer(m_device);
1001 const VkDescriptorTypeCount ds_type_count = {
1002 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1003 .count = 1,
1004 };
1005 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1006 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1007 .pNext = NULL,
1008 .count = 1,
1009 .pTypeCount = &ds_type_count,
1010 };
1011 VkDescriptorPool ds_pool;
1012 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1013 ASSERT_VK_SUCCESS(err);
1014 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1015
1016 const VkDescriptorSetLayoutBinding dsl_binding = {
1017 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1018 .count = 1,
1019 .stageFlags = VK_SHADER_STAGE_ALL,
1020 .pImmutableSamplers = NULL,
1021 };
1022
1023 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1024 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1025 .pNext = NULL,
1026 .count = 1,
1027 .pBinding = &dsl_binding,
1028 };
1029 VkDescriptorSetLayout ds_layout;
1030 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1031 ASSERT_VK_SUCCESS(err);
1032
1033 VkDescriptorSet descriptorSet;
1034 uint32_t ds_count = 0;
1035 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1036 ASSERT_VK_SUCCESS(err);
1037
1038 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1039 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1040 .pNext = NULL,
1041 .descriptorSetCount = 1,
1042 .pSetLayouts = &ds_layout,
1043 };
1044
1045 VkPipelineLayout pipeline_layout;
1046 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1047 ASSERT_VK_SUCCESS(err);
1048
1049 size_t shader_len = strlen(bindStateVertShaderText);
1050 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1051 void* pCode = malloc(codeSize);
1052
1053 /* try version 0 first: VkShaderStage followed by GLSL */
1054 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1055 ((uint32_t *) pCode)[1] = 0;
1056 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1057 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1058
1059 const VkShaderCreateInfo vs_ci = {
1060 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1061 .pNext = NULL,
1062 .codeSize = codeSize,
1063 .pCode = pCode,
1064 .flags = 0,
1065 };
1066 VkShader vs;
1067 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1068 ASSERT_VK_SUCCESS(err);
1069
1070 const VkPipelineShader vs_pipe_shader = {
1071 .stage = VK_SHADER_STAGE_VERTEX,
1072 .shader = vs,
1073 .linkConstBufferCount = 0,
1074 .pLinkConstBufferInfo = NULL,
1075 .pSpecializationInfo = NULL,
1076 };
1077 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1078 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1079 .pNext = NULL,
1080 .shader = vs_pipe_shader,
1081 };
1082 const VkGraphicsPipelineCreateInfo gp_ci = {
1083 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1084 .pNext = &pipe_vs_ci,
1085 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1086 .layout = pipeline_layout,
1087 };
1088
1089 VkPipeline pipeline;
1090 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1091 ASSERT_VK_SUCCESS(err);
1092
1093 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1094 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1095
1096 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1097 m_device->get_device_queue();
1098 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1099
1100 msgType = m_errorMonitor->GetState(&msgString);
1101 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1102 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1103 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1104 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001105}
1106
1107TEST_F(VkLayerTest, InvalidDynamicStateObject)
1108{
1109 // Create a valid cmd buffer
1110 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001111 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1112 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001113}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001114
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001115TEST_F(VkLayerTest, DSUpdateWithoutBegin)
1116{
1117 // Call vkUpdateDescriptors w/ valid DS, but before vkBeginDescriptorPoolUpdate
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001118 VK_DBG_MSG_TYPE msgType;
1119 std::string msgString;
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001120 VkResult err;
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001121
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001122 ASSERT_NO_FATAL_FAILURE(InitState());
1123 m_errorMonitor->ClearState();
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001124 //VkDescriptorSetObj descriptorSet(m_device);
1125 const VkDescriptorTypeCount ds_type_count = {
1126 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1127 .count = 1,
1128 };
1129 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1130 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1131 .pNext = NULL,
1132 .count = 1,
1133 .pTypeCount = &ds_type_count,
1134 };
1135 VkDescriptorPool ds_pool;
1136 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1137 ASSERT_VK_SUCCESS(err);
1138 const VkDescriptorSetLayoutBinding dsl_binding = {
1139 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1140 .count = 1,
1141 .stageFlags = VK_SHADER_STAGE_ALL,
1142 .pImmutableSamplers = NULL,
1143 };
1144
1145 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1146 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1147 .pNext = NULL,
1148 .count = 1,
1149 .pBinding = &dsl_binding,
1150 };
1151 VkDescriptorSetLayout ds_layout;
1152 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1153 ASSERT_VK_SUCCESS(err);
1154
1155 VkDescriptorSet descriptorSet;
1156 uint32_t ds_count = 0;
1157 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1158 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001159 // Should fail before we attempt update so don't care about update contents
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001160 vkUpdateDescriptors(m_device->device(), descriptorSet, 0, NULL);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001161 msgType = m_errorMonitor->GetState(&msgString);
1162 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptors w/o first calling vkBeginDescriptorPoolUpdate().";
1163 if (!strstr(msgString.c_str(),"You must call vkBeginDescriptorPoolUpdate() before ")) {
1164 // TODO : Hitting segF here due to DS Object cleanup error
1165 FAIL() << "Error received was not 'You must call vkBeginDescriptorPoolUpdate() before this call to vkUpdateDescriptors()!'";
1166 }
1167}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001168
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001169TEST_F(VkLayerTest, DSEndWithoutBegin)
1170{
1171 // With a valid pool & cmdBuffer, call vkEndDescriptorPoolUpdate
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001172 VK_DBG_MSG_TYPE msgType;
1173 std::string msgString;
1174 VkResult err;
1175
1176 ASSERT_NO_FATAL_FAILURE(InitState());
1177 m_errorMonitor->ClearState();
1178 VkCommandBufferObj cmdBuffer(m_device);
1179 const VkDescriptorTypeCount ds_type_count = {
1180 .type = VK_DESCRIPTOR_TYPE_SAMPLER,
1181 .count = 1,
1182 };
1183 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1184 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1185 .pNext = NULL,
1186 .count = 1,
1187 .pTypeCount = &ds_type_count,
1188 };
1189 VkDescriptorPool ds_pool;
1190 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1191 ASSERT_VK_SUCCESS(err);
1192 vkEndDescriptorPoolUpdate(m_device->device(), cmdBuffer.GetBufferHandle());
1193 msgType = m_errorMonitor->GetState(&msgString);
1194 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1195 if (!strstr(msgString.c_str(),"You must call vkBeginDescriptorPoolUpdate() before this call to vkEndDescriptorPoolUpdate()!")) {
1196 FAIL() << "Error received was not 'You must call vkBeginDescriptorPoolUpdate() before this call to vkEndDescriptorPoolUpdate()!'";
1197 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001198}
1199
1200TEST_F(VkLayerTest, DSBoundWithoutEnd)
1201{
1202 // With a valid pool and & cmdBuffer, do Begin/Update w/o End and then QueueSubmit
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001203 VK_DBG_MSG_TYPE msgType;
1204 std::string msgString;
1205 VkResult err;
1206
1207 ASSERT_NO_FATAL_FAILURE(InitState());
1208 m_errorMonitor->ClearState();
1209 VkCommandBufferObj cmdBuffer(m_device);
1210 const VkDescriptorTypeCount ds_type_count = {
1211 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1212 .count = 1,
1213 };
1214 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1215 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1216 .pNext = NULL,
1217 .count = 1,
1218 .pTypeCount = &ds_type_count,
1219 };
1220 VkDescriptorPool ds_pool;
1221 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1222 ASSERT_VK_SUCCESS(err);
1223 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1224
1225 const VkDescriptorSetLayoutBinding dsl_binding = {
1226 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1227 .count = 1,
1228 .stageFlags = VK_SHADER_STAGE_ALL,
1229 .pImmutableSamplers = NULL,
1230 };
1231
1232 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1233 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1234 .pNext = NULL,
1235 .count = 1,
1236 .pBinding = &dsl_binding,
1237 };
1238 VkDescriptorSetLayout ds_layout;
1239 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1240 ASSERT_VK_SUCCESS(err);
1241
1242 VkDescriptorSet descriptorSet;
1243 uint32_t ds_count = 0;
1244 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1245 ASSERT_VK_SUCCESS(err);
1246
1247 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1248 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1249 .pNext = NULL,
1250 .descriptorSetCount = 1,
1251 .pSetLayouts = &ds_layout,
1252 };
1253
1254 VkPipelineLayout pipeline_layout;
1255 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1256 ASSERT_VK_SUCCESS(err);
1257
1258 size_t shader_len = strlen(bindStateVertShaderText);
1259 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1260 void* pCode = malloc(codeSize);
1261
1262 /* try version 0 first: VkShaderStage followed by GLSL */
1263 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1264 ((uint32_t *) pCode)[1] = 0;
1265 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1266 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1267
1268 const VkShaderCreateInfo vs_ci = {
1269 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1270 .pNext = NULL,
1271 .codeSize = codeSize,
1272 .pCode = pCode,
1273 .flags = 0,
1274 };
1275 VkShader vs;
1276 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1277
1278 const VkPipelineShader vs_pipe_shader = {
1279 .stage = VK_SHADER_STAGE_VERTEX,
1280 .shader = vs,
1281 .linkConstBufferCount = 0,
1282 .pLinkConstBufferInfo = NULL,
1283 .pSpecializationInfo = NULL,
1284 };
1285 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1286 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1287 .pNext = NULL,
1288 .shader = vs_pipe_shader,
1289 };
1290 const VkGraphicsPipelineCreateInfo gp_ci = {
1291 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1292 .pNext = &pipe_vs_ci,
1293 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1294 .layout = pipeline_layout,
1295 };
1296
1297 VkPipeline pipeline;
1298 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1299 ASSERT_VK_SUCCESS(err);
1300
1301 err= cmdBuffer.BeginCommandBuffer();
1302 ASSERT_VK_SUCCESS(err);
1303 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1304 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1305 cmdBuffer.EndCommandBuffer();
1306
1307 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1308 m_device->get_device_queue();
1309 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1310
1311 msgType = m_errorMonitor->GetState(&msgString);
1312 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1313 if (!strstr(msgString.c_str(),"You must call vkEndDescriptorPoolUpdate() before this call to vkQueueSubmit()!")) {
1314 FAIL() << "Error received was not 'You must call vkEndDescriptorPoolUpdate() before this call to vkQueueSubmit()!'";
1315 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001316}
1317
1318TEST_F(VkLayerTest, VtxBufferBadIndex)
1319{
1320 // Bind VBO out-of-bounds for given PSO
1321}
1322
1323TEST_F(VkLayerTest, DSTypeMismatch)
1324{
1325 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
1326}
1327
1328TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1329{
1330 // For overlapping Update, have arrayIndex exceed that of layout
1331}
1332
1333TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1334{
1335 // Create layout w/ count of 1 and attempt update to that layout w/ count > 1
1336}
1337
1338TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1339{
1340 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
1341}
1342
1343TEST_F(VkLayerTest, NumSamplesMismatch)
1344{
1345 // Initiate a draw where MSAA samples doesn't match FB sampleCount
1346 // Initiate a draw where MSAA samples doesn't match RenderPass sampleCount
1347}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001348#endif
1349#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001350#if GTEST_IS_THREADSAFE
1351struct thread_data_struct {
1352 VkCmdBuffer cmdBuffer;
1353 VkEvent event;
1354 bool bailout;
1355};
1356
1357extern "C" void *AddToCommandBuffer(void *arg)
1358{
1359 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1360 std::string msgString;
1361
1362 for (int i = 0; i<10000; i++) {
1363 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1364 if (data->bailout) {
1365 break;
1366 }
1367 }
1368 return NULL;
1369}
1370
1371TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1372{
1373 VK_DBG_MSG_TYPE msgType;
1374 std::string msgString;
1375 pthread_t thread;
1376 pthread_attr_t thread_attr;
1377
1378 ASSERT_NO_FATAL_FAILURE(InitState());
1379 ASSERT_NO_FATAL_FAILURE(InitViewport());
1380 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1381
1382 VkCommandBufferObj cmdBuffer(m_device);
1383
1384 m_errorMonitor->ClearState();
1385 pthread_attr_init(&thread_attr);
1386 BeginCommandBuffer(cmdBuffer);
1387
1388 VkEventCreateInfo event_info;
1389 VkEvent event;
1390 VkMemoryRequirements mem_req;
1391 size_t data_size = sizeof(mem_req);
1392 VkResult err;
1393
1394 memset(&event_info, 0, sizeof(event_info));
1395 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1396
1397 err = vkCreateEvent(device(), &event_info, &event);
1398 ASSERT_VK_SUCCESS(err);
1399
1400 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1401 &data_size, &mem_req);
1402 ASSERT_VK_SUCCESS(err);
1403
1404 VkMemoryAllocInfo mem_info;
1405 VkDeviceMemory event_mem;
1406
1407 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1408
1409 memset(&mem_info, 0, sizeof(mem_info));
1410 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1411 mem_info.allocationSize = mem_req.size;
1412 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1413 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1414 err = vkAllocMemory(device(), &mem_info, &event_mem);
1415 ASSERT_VK_SUCCESS(err);
1416
1417 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, 0, event_mem, 0);
1418 ASSERT_VK_SUCCESS(err);
1419
1420 err = vkResetEvent(device(), event);
1421 ASSERT_VK_SUCCESS(err);
1422
1423 struct thread_data_struct data;
1424 data.cmdBuffer = cmdBuffer.obj();
1425 data.event = event;
1426 data.bailout = false;
1427 m_errorMonitor->SetBailout(&data.bailout);
1428 // Add many entries to command buffer from another thread.
1429 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1430 // Add many entries to command buffer from this thread at the same time.
1431 AddToCommandBuffer(&data);
1432 pthread_join(thread, NULL);
1433 EndCommandBuffer(cmdBuffer);
1434
1435 msgType = m_errorMonitor->GetState(&msgString);
1436 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using one VkCommandBufferObj in two threads";
1437 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001438 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001439 }
1440
1441}
1442#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001443#endif
Tony Barbour30486ea2015-04-07 13:44:53 -06001444int main(int argc, char **argv) {
1445 int result;
1446
1447 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06001448 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06001449
1450 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
1451
1452 result = RUN_ALL_TESTS();
1453
Tony Barbour01999182015-04-09 12:58:51 -06001454 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06001455 return result;
1456}