blob: dd07b126db16acbdf74fc01f178d98b1df117b60 [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 ")) {
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001164 FAIL() << "Error received was not 'You must call vkBeginDescriptorPoolUpdate() before this call to vkUpdateDescriptors()!'";
1165 }
1166}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001167
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001168TEST_F(VkLayerTest, DSEndWithoutBegin)
1169{
1170 // With a valid pool & cmdBuffer, call vkEndDescriptorPoolUpdate
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001171 VK_DBG_MSG_TYPE msgType;
1172 std::string msgString;
1173 VkResult err;
1174
1175 ASSERT_NO_FATAL_FAILURE(InitState());
1176 m_errorMonitor->ClearState();
1177 VkCommandBufferObj cmdBuffer(m_device);
1178 const VkDescriptorTypeCount ds_type_count = {
1179 .type = VK_DESCRIPTOR_TYPE_SAMPLER,
1180 .count = 1,
1181 };
1182 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1183 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1184 .pNext = NULL,
1185 .count = 1,
1186 .pTypeCount = &ds_type_count,
1187 };
1188 VkDescriptorPool ds_pool;
1189 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1190 ASSERT_VK_SUCCESS(err);
1191 vkEndDescriptorPoolUpdate(m_device->device(), cmdBuffer.GetBufferHandle());
1192 msgType = m_errorMonitor->GetState(&msgString);
1193 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1194 if (!strstr(msgString.c_str(),"You must call vkBeginDescriptorPoolUpdate() before this call to vkEndDescriptorPoolUpdate()!")) {
1195 FAIL() << "Error received was not 'You must call vkBeginDescriptorPoolUpdate() before this call to vkEndDescriptorPoolUpdate()!'";
1196 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001197}
1198
1199TEST_F(VkLayerTest, DSBoundWithoutEnd)
1200{
1201 // With a valid pool and & cmdBuffer, do Begin/Update w/o End and then QueueSubmit
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001202 VK_DBG_MSG_TYPE msgType;
1203 std::string msgString;
1204 VkResult err;
1205
1206 ASSERT_NO_FATAL_FAILURE(InitState());
1207 m_errorMonitor->ClearState();
1208 VkCommandBufferObj cmdBuffer(m_device);
1209 const VkDescriptorTypeCount ds_type_count = {
1210 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1211 .count = 1,
1212 };
1213 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1214 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1215 .pNext = NULL,
1216 .count = 1,
1217 .pTypeCount = &ds_type_count,
1218 };
1219 VkDescriptorPool ds_pool;
1220 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1221 ASSERT_VK_SUCCESS(err);
1222 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1223
1224 const VkDescriptorSetLayoutBinding dsl_binding = {
1225 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1226 .count = 1,
1227 .stageFlags = VK_SHADER_STAGE_ALL,
1228 .pImmutableSamplers = NULL,
1229 };
1230
1231 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1232 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1233 .pNext = NULL,
1234 .count = 1,
1235 .pBinding = &dsl_binding,
1236 };
1237 VkDescriptorSetLayout ds_layout;
1238 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1239 ASSERT_VK_SUCCESS(err);
1240
1241 VkDescriptorSet descriptorSet;
1242 uint32_t ds_count = 0;
1243 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1244 ASSERT_VK_SUCCESS(err);
1245
1246 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1247 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1248 .pNext = NULL,
1249 .descriptorSetCount = 1,
1250 .pSetLayouts = &ds_layout,
1251 };
1252
1253 VkPipelineLayout pipeline_layout;
1254 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1255 ASSERT_VK_SUCCESS(err);
1256
1257 size_t shader_len = strlen(bindStateVertShaderText);
1258 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1259 void* pCode = malloc(codeSize);
1260
1261 /* try version 0 first: VkShaderStage followed by GLSL */
1262 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1263 ((uint32_t *) pCode)[1] = 0;
1264 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1265 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1266
1267 const VkShaderCreateInfo vs_ci = {
1268 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1269 .pNext = NULL,
1270 .codeSize = codeSize,
1271 .pCode = pCode,
1272 .flags = 0,
1273 };
1274 VkShader vs;
1275 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1276
1277 const VkPipelineShader vs_pipe_shader = {
1278 .stage = VK_SHADER_STAGE_VERTEX,
1279 .shader = vs,
1280 .linkConstBufferCount = 0,
1281 .pLinkConstBufferInfo = NULL,
1282 .pSpecializationInfo = NULL,
1283 };
1284 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1285 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1286 .pNext = NULL,
1287 .shader = vs_pipe_shader,
1288 };
1289 const VkGraphicsPipelineCreateInfo gp_ci = {
1290 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1291 .pNext = &pipe_vs_ci,
1292 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1293 .layout = pipeline_layout,
1294 };
1295
1296 VkPipeline pipeline;
1297 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1298 ASSERT_VK_SUCCESS(err);
1299
1300 err= cmdBuffer.BeginCommandBuffer();
1301 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001302
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001303 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
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001321 VK_DBG_MSG_TYPE msgType;
1322 std::string msgString;
1323 VkResult err;
1324
1325 ASSERT_NO_FATAL_FAILURE(InitState());
1326 m_errorMonitor->ClearState();
1327 VkCommandBufferObj cmdBuffer(m_device);
1328 const VkDescriptorTypeCount ds_type_count = {
1329 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1330 .count = 1,
1331 };
1332 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1333 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1334 .pNext = NULL,
1335 .count = 1,
1336 .pTypeCount = &ds_type_count,
1337 };
1338 VkDescriptorPool ds_pool;
1339 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1340 ASSERT_VK_SUCCESS(err);
1341 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1342
1343 const VkDescriptorSetLayoutBinding dsl_binding = {
1344 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1345 .count = 1,
1346 .stageFlags = VK_SHADER_STAGE_ALL,
1347 .pImmutableSamplers = NULL,
1348 };
1349
1350 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1351 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1352 .pNext = NULL,
1353 .count = 1,
1354 .pBinding = &dsl_binding,
1355 };
1356 VkDescriptorSetLayout ds_layout;
1357 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1358 ASSERT_VK_SUCCESS(err);
1359
1360 VkDescriptorSet descriptorSet;
1361 uint32_t ds_count = 0;
1362 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1363 ASSERT_VK_SUCCESS(err);
1364
1365 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1366 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1367 .pNext = NULL,
1368 .descriptorSetCount = 1,
1369 .pSetLayouts = &ds_layout,
1370 };
1371
1372 VkPipelineLayout pipeline_layout;
1373 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1374 ASSERT_VK_SUCCESS(err);
1375
1376 size_t shader_len = strlen(bindStateVertShaderText);
1377 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1378 void* pCode = malloc(codeSize);
1379
1380 /* try version 0 first: VkShaderStage followed by GLSL */
1381 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1382 ((uint32_t *) pCode)[1] = 0;
1383 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1384 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1385
1386 const VkShaderCreateInfo vs_ci = {
1387 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1388 .pNext = NULL,
1389 .codeSize = codeSize,
1390 .pCode = pCode,
1391 .flags = 0,
1392 };
1393 VkShader vs;
1394 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1395
1396 const VkPipelineShader vs_pipe_shader = {
1397 .stage = VK_SHADER_STAGE_VERTEX,
1398 .shader = vs,
1399 .linkConstBufferCount = 0,
1400 .pLinkConstBufferInfo = NULL,
1401 .pSpecializationInfo = NULL,
1402 };
1403 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1404 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1405 .pNext = NULL,
1406 .shader = vs_pipe_shader,
1407 };
1408 const VkGraphicsPipelineCreateInfo gp_ci = {
1409 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1410 .pNext = &pipe_vs_ci,
1411 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1412 .layout = pipeline_layout,
1413 };
1414
1415 VkPipeline pipeline;
1416 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1417 ASSERT_VK_SUCCESS(err);
1418
1419 err= cmdBuffer.BeginCommandBuffer();
1420 ASSERT_VK_SUCCESS(err);
1421 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1422 // Should error before calling to driver so don't care about actual data
1423 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1424
1425 msgType = m_errorMonitor->GetState(&msgString);
1426 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
1427 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1428 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1429 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001430}
1431
1432TEST_F(VkLayerTest, DSTypeMismatch)
1433{
1434 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001435 VK_DBG_MSG_TYPE msgType;
1436 std::string msgString;
1437 VkResult err;
1438
1439 ASSERT_NO_FATAL_FAILURE(InitState());
1440 m_errorMonitor->ClearState();
1441 //VkDescriptorSetObj descriptorSet(m_device);
1442 const VkDescriptorTypeCount ds_type_count = {
1443 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1444 .count = 1,
1445 };
1446 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1447 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1448 .pNext = NULL,
1449 .count = 1,
1450 .pTypeCount = &ds_type_count,
1451 };
1452 VkDescriptorPool ds_pool;
1453 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1454 ASSERT_VK_SUCCESS(err);
1455 const VkDescriptorSetLayoutBinding dsl_binding = {
1456 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1457 .count = 1,
1458 .stageFlags = VK_SHADER_STAGE_ALL,
1459 .pImmutableSamplers = NULL,
1460 };
1461
1462 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1463 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1464 .pNext = NULL,
1465 .count = 1,
1466 .pBinding = &dsl_binding,
1467 };
1468 VkDescriptorSetLayout ds_layout;
1469 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1470 ASSERT_VK_SUCCESS(err);
1471
1472 VkDescriptorSet descriptorSet;
1473 uint32_t ds_count = 0;
1474 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1475 ASSERT_VK_SUCCESS(err);
1476 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1477
1478 const VkSamplerCreateInfo sampler_ci = {
1479 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1480 .pNext = NULL,
1481 .magFilter = VK_TEX_FILTER_NEAREST,
1482 .minFilter = VK_TEX_FILTER_NEAREST,
1483 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1484 .addressU = VK_TEX_ADDRESS_CLAMP,
1485 .addressV = VK_TEX_ADDRESS_CLAMP,
1486 .addressW = VK_TEX_ADDRESS_CLAMP,
1487 .mipLodBias = 1.0,
1488 .maxAnisotropy = 1,
1489 .compareOp = VK_COMPARE_OP_NEVER,
1490 .minLod = 1.0,
1491 .maxLod = 1.0,
1492 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1493 };
1494 VkSampler sampler;
1495 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1496 ASSERT_VK_SUCCESS(err);
1497
1498 VkUpdateSamplers *pSamplerUpdate = (VkUpdateSamplers*)malloc(sizeof(VkUpdateSamplers));
1499 // This is a mismatched type for the layout which expects BUFFER
1500 pSamplerUpdate->sType = VK_STRUCTURE_TYPE_UPDATE_SAMPLERS;
1501 pSamplerUpdate->pNext = NULL;
1502 pSamplerUpdate->binding = 0;
1503 pSamplerUpdate->arrayIndex = 0;
1504 pSamplerUpdate->count = 1;
1505 pSamplerUpdate->pSamplers = &sampler;
1506 const void** ppUpdate = (const void**)&pSamplerUpdate;
1507 vkUpdateDescriptors(m_device->device(), descriptorSet, 1, ppUpdate);
1508 msgType = m_errorMonitor->GetState(&msgString);
1509 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating BUFFER Descriptor w/ incorrect type of SAMPLER.";
1510 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_UPDATE_SAMPLERS does not match ")) {
1511 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_UPDATE_SAMPLERS does not match overlapping binding type!'";
1512 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001513}
1514
1515TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1516{
1517 // For overlapping Update, have arrayIndex exceed that of layout
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001518 VK_DBG_MSG_TYPE msgType;
1519 std::string msgString;
1520 VkResult err;
1521
1522 ASSERT_NO_FATAL_FAILURE(InitState());
1523 m_errorMonitor->ClearState();
1524 //VkDescriptorSetObj descriptorSet(m_device);
1525 const VkDescriptorTypeCount ds_type_count = {
1526 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1527 .count = 1,
1528 };
1529 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1530 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1531 .pNext = NULL,
1532 .count = 1,
1533 .pTypeCount = &ds_type_count,
1534 };
1535 VkDescriptorPool ds_pool;
1536 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1537 ASSERT_VK_SUCCESS(err);
1538 const VkDescriptorSetLayoutBinding dsl_binding = {
1539 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1540 .count = 1,
1541 .stageFlags = VK_SHADER_STAGE_ALL,
1542 .pImmutableSamplers = NULL,
1543 };
1544
1545 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1546 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1547 .pNext = NULL,
1548 .count = 1,
1549 .pBinding = &dsl_binding,
1550 };
1551 VkDescriptorSetLayout ds_layout;
1552 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1553 ASSERT_VK_SUCCESS(err);
1554
1555 VkDescriptorSet descriptorSet;
1556 uint32_t ds_count = 0;
1557 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1558 ASSERT_VK_SUCCESS(err);
1559 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1560
1561 const VkSamplerCreateInfo sampler_ci = {
1562 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1563 .pNext = NULL,
1564 .magFilter = VK_TEX_FILTER_NEAREST,
1565 .minFilter = VK_TEX_FILTER_NEAREST,
1566 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1567 .addressU = VK_TEX_ADDRESS_CLAMP,
1568 .addressV = VK_TEX_ADDRESS_CLAMP,
1569 .addressW = VK_TEX_ADDRESS_CLAMP,
1570 .mipLodBias = 1.0,
1571 .maxAnisotropy = 1,
1572 .compareOp = VK_COMPARE_OP_NEVER,
1573 .minLod = 1.0,
1574 .maxLod = 1.0,
1575 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1576 };
1577 VkSampler sampler;
1578 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1579 ASSERT_VK_SUCCESS(err);
1580 // This is the wrong type, but out of bounds will be flagged first
1581 VkUpdateSamplers *pSamplerUpdate = (VkUpdateSamplers*)malloc(sizeof(VkUpdateSamplers));
1582 pSamplerUpdate->sType = VK_STRUCTURE_TYPE_UPDATE_SAMPLERS;
1583 pSamplerUpdate->pNext = NULL;
1584 pSamplerUpdate->binding = 0;
1585 pSamplerUpdate->arrayIndex = 1; /* This index out of bounds for the update */
1586 pSamplerUpdate->count = 1;
1587 pSamplerUpdate->pSamplers = &sampler;
1588 const void** ppUpdate = (const void**)&pSamplerUpdate;
1589 vkUpdateDescriptors(m_device->device(), descriptorSet, 1, ppUpdate);
1590 msgType = m_errorMonitor->GetState(&msgString);
1591 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ index out of bounds.";
1592 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_UPDATE_SAMPLERS is out of bounds for matching binding")) {
1593 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_UPDATE_SAMPLERS is out of bounds for matching binding...'";
1594 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001595}
1596
1597TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1598{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001599 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
1600 VK_DBG_MSG_TYPE msgType;
1601 std::string msgString;
1602 VkResult err;
1603
1604 ASSERT_NO_FATAL_FAILURE(InitState());
1605 m_errorMonitor->ClearState();
1606 //VkDescriptorSetObj descriptorSet(m_device);
1607 const VkDescriptorTypeCount ds_type_count = {
1608 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1609 .count = 1,
1610 };
1611 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1612 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1613 .pNext = NULL,
1614 .count = 1,
1615 .pTypeCount = &ds_type_count,
1616 };
1617 VkDescriptorPool ds_pool;
1618 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1619 ASSERT_VK_SUCCESS(err);
1620 const VkDescriptorSetLayoutBinding dsl_binding = {
1621 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1622 .count = 1,
1623 .stageFlags = VK_SHADER_STAGE_ALL,
1624 .pImmutableSamplers = NULL,
1625 };
1626
1627 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1628 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1629 .pNext = NULL,
1630 .count = 1,
1631 .pBinding = &dsl_binding,
1632 };
1633 VkDescriptorSetLayout ds_layout;
1634 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1635 ASSERT_VK_SUCCESS(err);
1636
1637 VkDescriptorSet descriptorSet;
1638 uint32_t ds_count = 0;
1639 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1640 ASSERT_VK_SUCCESS(err);
1641 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1642
1643 const VkSamplerCreateInfo sampler_ci = {
1644 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1645 .pNext = NULL,
1646 .magFilter = VK_TEX_FILTER_NEAREST,
1647 .minFilter = VK_TEX_FILTER_NEAREST,
1648 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1649 .addressU = VK_TEX_ADDRESS_CLAMP,
1650 .addressV = VK_TEX_ADDRESS_CLAMP,
1651 .addressW = VK_TEX_ADDRESS_CLAMP,
1652 .mipLodBias = 1.0,
1653 .maxAnisotropy = 1,
1654 .compareOp = VK_COMPARE_OP_NEVER,
1655 .minLod = 1.0,
1656 .maxLod = 1.0,
1657 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1658 };
1659 VkSampler sampler;
1660 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1661 ASSERT_VK_SUCCESS(err);
1662 // This is the wrong type, but out of bounds will be flagged first
1663 VkUpdateSamplers *pSamplerUpdate = (VkUpdateSamplers*)malloc(sizeof(VkUpdateSamplers));
1664 pSamplerUpdate->sType = VK_STRUCTURE_TYPE_UPDATE_SAMPLERS;
1665 pSamplerUpdate->pNext = NULL;
1666 pSamplerUpdate->binding = 2; /* This binding too big for the update */
1667 pSamplerUpdate->arrayIndex = 0;
1668 pSamplerUpdate->count = 1;
1669 pSamplerUpdate->pSamplers = &sampler;
1670 const void** ppUpdate = (const void**)&pSamplerUpdate;
1671 vkUpdateDescriptors(m_device->device(), descriptorSet, 1, ppUpdate);
1672 msgType = m_errorMonitor->GetState(&msgString);
1673 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ count too large for layout.";
1674 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1675 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1676 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001677}
1678
1679TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1680{
1681 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001682 VK_DBG_MSG_TYPE msgType;
1683 std::string msgString;
1684 VkResult err;
1685
1686 ASSERT_NO_FATAL_FAILURE(InitState());
1687 m_errorMonitor->ClearState();
1688 //VkDescriptorSetObj descriptorSet(m_device);
1689 const VkDescriptorTypeCount ds_type_count = {
1690 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1691 .count = 1,
1692 };
1693 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1694 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1695 .pNext = NULL,
1696 .count = 1,
1697 .pTypeCount = &ds_type_count,
1698 };
1699 VkDescriptorPool ds_pool;
1700 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1701 ASSERT_VK_SUCCESS(err);
1702 const VkDescriptorSetLayoutBinding dsl_binding = {
1703 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1704 .count = 1,
1705 .stageFlags = VK_SHADER_STAGE_ALL,
1706 .pImmutableSamplers = NULL,
1707 };
1708
1709 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1710 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1711 .pNext = NULL,
1712 .count = 1,
1713 .pBinding = &dsl_binding,
1714 };
1715 VkDescriptorSetLayout ds_layout;
1716 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1717 ASSERT_VK_SUCCESS(err);
1718
1719 VkDescriptorSet descriptorSet;
1720 uint32_t ds_count = 0;
1721 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1722 ASSERT_VK_SUCCESS(err);
1723 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1724
1725 const VkSamplerCreateInfo sampler_ci = {
1726 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1727 .pNext = NULL,
1728 .magFilter = VK_TEX_FILTER_NEAREST,
1729 .minFilter = VK_TEX_FILTER_NEAREST,
1730 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1731 .addressU = VK_TEX_ADDRESS_CLAMP,
1732 .addressV = VK_TEX_ADDRESS_CLAMP,
1733 .addressW = VK_TEX_ADDRESS_CLAMP,
1734 .mipLodBias = 1.0,
1735 .maxAnisotropy = 1,
1736 .compareOp = VK_COMPARE_OP_NEVER,
1737 .minLod = 1.0,
1738 .maxLod = 1.0,
1739 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1740 };
1741 VkSampler sampler;
1742 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1743 ASSERT_VK_SUCCESS(err);
1744 // This is the wrong type, but out of bounds will be flagged first
1745 VkUpdateSamplers *pSamplerUpdate = (VkUpdateSamplers*)malloc(sizeof(VkUpdateSamplers));
1746 pSamplerUpdate->sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1747 pSamplerUpdate->pNext = NULL;
1748 pSamplerUpdate->binding = 0;
1749 pSamplerUpdate->arrayIndex = 0;
1750 pSamplerUpdate->count = 1;
1751 pSamplerUpdate->pSamplers = &sampler;
1752 const void** ppUpdate = (const void**)&pSamplerUpdate;
1753 vkUpdateDescriptors(m_device->device(), descriptorSet, 1, ppUpdate);
1754 msgType = m_errorMonitor->GetState(&msgString);
1755 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ invalid struct type.";
1756 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1757 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1758 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001759}
1760
1761TEST_F(VkLayerTest, NumSamplesMismatch)
1762{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001763 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1764 VK_DBG_MSG_TYPE msgType;
1765 std::string msgString;
1766 VkResult err;
1767
1768 ASSERT_NO_FATAL_FAILURE(InitState());
1769 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1770 m_errorMonitor->ClearState();
1771 VkCommandBufferObj cmdBuffer(m_device);
1772 const VkDescriptorTypeCount ds_type_count = {
1773 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1774 .count = 1,
1775 };
1776 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1777 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1778 .pNext = NULL,
1779 .count = 1,
1780 .pTypeCount = &ds_type_count,
1781 };
1782 VkDescriptorPool ds_pool;
1783 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1784 ASSERT_VK_SUCCESS(err);
1785 vkBeginDescriptorPoolUpdate(m_device->device(), VK_DESCRIPTOR_UPDATE_MODE_COPY);
1786
1787 const VkDescriptorSetLayoutBinding dsl_binding = {
1788 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1789 .count = 1,
1790 .stageFlags = VK_SHADER_STAGE_ALL,
1791 .pImmutableSamplers = NULL,
1792 };
1793
1794 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1795 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1796 .pNext = NULL,
1797 .count = 1,
1798 .pBinding = &dsl_binding,
1799 };
1800 VkDescriptorSetLayout ds_layout;
1801 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1802 ASSERT_VK_SUCCESS(err);
1803
1804 VkDescriptorSet descriptorSet;
1805 uint32_t ds_count = 0;
1806 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1807 ASSERT_VK_SUCCESS(err);
1808
1809 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1810 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1811 .pNext = NULL,
1812 .samples = 1,
1813 .multisampleEnable = 1,
1814 .sampleShadingEnable = 0,
1815 .minSampleShading = 1.0,
1816 .sampleMask = 15,
1817 };
1818
1819 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1820 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1821 .pNext = NULL,
1822 .descriptorSetCount = 1,
1823 .pSetLayouts = &ds_layout,
1824 };
1825
1826 VkPipelineLayout pipeline_layout;
1827 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1828 ASSERT_VK_SUCCESS(err);
1829
1830 size_t shader_len = strlen(bindStateVertShaderText);
1831 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1832 void* pCode = malloc(codeSize);
1833
1834 /* try version 0 first: VkShaderStage followed by GLSL */
1835 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1836 ((uint32_t *) pCode)[1] = 0;
1837 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1838 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1839
1840 const VkShaderCreateInfo vs_ci = {
1841 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1842 .pNext = NULL,
1843 .codeSize = codeSize,
1844 .pCode = pCode,
1845 .flags = 0,
1846 };
1847 VkShader vs;
1848 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1849 ASSERT_VK_SUCCESS(err);
1850
1851 const VkPipelineShader vs_pipe_shader = {
1852 .stage = VK_SHADER_STAGE_VERTEX,
1853 .shader = vs,
1854 .linkConstBufferCount = 0,
1855 .pLinkConstBufferInfo = NULL,
1856 .pSpecializationInfo = NULL,
1857 };
1858 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1859 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1860 .pNext = &pipe_ms_state_ci,
1861 .shader = vs_pipe_shader,
1862 };
1863 const VkGraphicsPipelineCreateInfo gp_ci = {
1864 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1865 .pNext = &pipe_vs_ci,
1866 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1867 .layout = pipeline_layout,
1868 };
1869
1870 VkPipeline pipeline;
1871 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1872 ASSERT_VK_SUCCESS(err);
1873
1874 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1875 BeginCommandBuffer(cmdBuffer);
1876 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1877
1878 msgType = m_errorMonitor->GetState(&msgString);
1879 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
1880 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1881 FAIL() << "Error received was not 'Num samples mismatch!...'";
1882 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001883}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001884#endif
1885#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001886#if GTEST_IS_THREADSAFE
1887struct thread_data_struct {
1888 VkCmdBuffer cmdBuffer;
1889 VkEvent event;
1890 bool bailout;
1891};
1892
1893extern "C" void *AddToCommandBuffer(void *arg)
1894{
1895 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1896 std::string msgString;
1897
1898 for (int i = 0; i<10000; i++) {
1899 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1900 if (data->bailout) {
1901 break;
1902 }
1903 }
1904 return NULL;
1905}
1906
1907TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1908{
1909 VK_DBG_MSG_TYPE msgType;
1910 std::string msgString;
1911 pthread_t thread;
1912 pthread_attr_t thread_attr;
1913
1914 ASSERT_NO_FATAL_FAILURE(InitState());
1915 ASSERT_NO_FATAL_FAILURE(InitViewport());
1916 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1917
1918 VkCommandBufferObj cmdBuffer(m_device);
1919
1920 m_errorMonitor->ClearState();
1921 pthread_attr_init(&thread_attr);
1922 BeginCommandBuffer(cmdBuffer);
1923
1924 VkEventCreateInfo event_info;
1925 VkEvent event;
1926 VkMemoryRequirements mem_req;
1927 size_t data_size = sizeof(mem_req);
1928 VkResult err;
1929
1930 memset(&event_info, 0, sizeof(event_info));
1931 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1932
1933 err = vkCreateEvent(device(), &event_info, &event);
1934 ASSERT_VK_SUCCESS(err);
1935
1936 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1937 &data_size, &mem_req);
1938 ASSERT_VK_SUCCESS(err);
1939
1940 VkMemoryAllocInfo mem_info;
1941 VkDeviceMemory event_mem;
1942
1943 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1944
1945 memset(&mem_info, 0, sizeof(mem_info));
1946 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1947 mem_info.allocationSize = mem_req.size;
1948 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1949 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1950 err = vkAllocMemory(device(), &mem_info, &event_mem);
1951 ASSERT_VK_SUCCESS(err);
1952
1953 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, 0, event_mem, 0);
1954 ASSERT_VK_SUCCESS(err);
1955
1956 err = vkResetEvent(device(), event);
1957 ASSERT_VK_SUCCESS(err);
1958
1959 struct thread_data_struct data;
1960 data.cmdBuffer = cmdBuffer.obj();
1961 data.event = event;
1962 data.bailout = false;
1963 m_errorMonitor->SetBailout(&data.bailout);
1964 // Add many entries to command buffer from another thread.
1965 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1966 // Add many entries to command buffer from this thread at the same time.
1967 AddToCommandBuffer(&data);
1968 pthread_join(thread, NULL);
1969 EndCommandBuffer(cmdBuffer);
1970
1971 msgType = m_errorMonitor->GetState(&msgString);
1972 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using one VkCommandBufferObj in two threads";
1973 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001974 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001975 }
1976
1977}
1978#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001979#endif
Tony Barbour30486ea2015-04-07 13:44:53 -06001980int main(int argc, char **argv) {
1981 int result;
1982
1983 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06001984 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06001985
1986 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
1987
1988 result = RUN_ALL_TESTS();
1989
Tony Barbour01999182015-04-09 12:58:51 -06001990 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06001991 return result;
1992}