blob: 891eaa908d28cbdb9d1ab3487b21da95d15a6c5f [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
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050042static const char bindStateVertShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050043 "#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
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050052static const char bindStateFragShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050053 "#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() {
Chris Forbesd0f3f442015-05-25 11:13:00 +1200144 const char *extension_names[] = {"MemTracker", "ObjectTracker", "Threading", "DrawState", "ShaderChecker"};
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");
Chris Forbesd0f3f442015-05-25 11:13:00 +1200176 setLayerOptionEnum("ShaderCheckerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500177
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600178 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600179 this->app_info.pNext = NULL;
180 this->app_info.pAppName = "layer_tests";
181 this->app_info.appVersion = 1;
182 this->app_info.pEngineName = "unittest";
183 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600184 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600185
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600186 m_errorMonitor = new ErrorMonitor;
187 InitFramework(extensions, myDbgFunc, m_errorMonitor);
188
Tony Barbour30486ea2015-04-07 13:44:53 -0600189 }
190
191 virtual void TearDown() {
192 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600193 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600194 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600195 }
196};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500197
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600198VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600199{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600200 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600201
202 result = cmdBuffer.BeginCommandBuffer();
203
204 /*
205 * For render test all drawing happens in a single render pass
206 * on a single command buffer.
207 */
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600208 if (VK_SUCCESS == result) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600209 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
210 }
211
212 return result;
213}
214
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600215VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600216{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600217 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600218
219 cmdBuffer.EndRenderPass(renderPass());
220
221 result = cmdBuffer.EndCommandBuffer();
222
223 return result;
224}
225
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500226void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
227{
228 // Create identity matrix
229 int i;
230 struct vktriangle_vs_uniform data;
231
232 glm::mat4 Projection = glm::mat4(1.0f);
233 glm::mat4 View = glm::mat4(1.0f);
234 glm::mat4 Model = glm::mat4(1.0f);
235 glm::mat4 MVP = Projection * View * Model;
236 const int matrixSize = sizeof(MVP);
237 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
238
239 memcpy(&data.mvp, &MVP[0][0], matrixSize);
240
241 static const Vertex tri_data[] =
242 {
243 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
244 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
245 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
246 };
247
248 for (i=0; i<3; i++) {
249 data.position[i][0] = tri_data[i].posX;
250 data.position[i][1] = tri_data[i].posY;
251 data.position[i][2] = tri_data[i].posZ;
252 data.position[i][3] = tri_data[i].posW;
253 data.color[i][0] = tri_data[i].r;
254 data.color[i][1] = tri_data[i].g;
255 data.color[i][2] = tri_data[i].b;
256 data.color[i][3] = tri_data[i].a;
257 }
258
259 ASSERT_NO_FATAL_FAILURE(InitState());
260 ASSERT_NO_FATAL_FAILURE(InitViewport());
261
262 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
263
264 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
265 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
266
267 VkPipelineObj pipelineobj(m_device);
268 pipelineobj.AddShader(&vs);
269 pipelineobj.AddShader(&ps);
270
271 VkDescriptorSetObj descriptorSet(m_device);
272 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
273
274 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
275 VkCommandBufferObj cmdBuffer(m_device);
276 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
277
278 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
279
280 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
281
282 // render triangle
283 cmdBuffer.Draw(0, 3, 0, 1);
284
285 // finalize recording of the command buffer
286 EndCommandBuffer(cmdBuffer);
287
288 cmdBuffer.QueueCommandBuffer();
289}
290
291void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
292{
293 if (m_depthStencil->Initialized()) {
294 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
295 } else {
296 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
297 }
298
299 cmdBuffer->PrepareAttachments();
300 if ((failMask & BsoFailRaster) != BsoFailRaster) {
301 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
302 }
303 if ((failMask & BsoFailViewport) != BsoFailViewport) {
304 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
305 }
306 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
307 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
308 }
309 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
310 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
311 }
312 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
313 pipelineobj.CreateVKPipeline(descriptorSet);
314 cmdBuffer->BindPipeline(pipelineobj);
315 cmdBuffer->BindDescriptorSet(descriptorSet);
316}
317
318// ********************************************************************************************************************
319// ********************************************************************************************************************
320// ********************************************************************************************************************
321// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600322#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500323TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
324{
325 vk_testing::Fence testFence;
326 VK_DBG_MSG_TYPE msgType;
327 std::string msgString;
328
329 VkFenceCreateInfo fenceInfo = {};
330 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
331 fenceInfo.pNext = NULL;
332 fenceInfo.flags = 0;
333
334 ASSERT_NO_FATAL_FAILURE(InitState());
335 ASSERT_NO_FATAL_FAILURE(InitViewport());
336 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
337
338 VkCommandBufferObj cmdBuffer(m_device);
339 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
340
341 BeginCommandBuffer(cmdBuffer);
342 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
343 EndCommandBuffer(cmdBuffer);
344
345 testFence.init(*m_device, fenceInfo);
346
347 // Bypass framework since it does the waits automatically
348 VkResult err = VK_SUCCESS;
349 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
350 ASSERT_VK_SUCCESS( err );
351
352 m_errorMonitor->ClearState();
353 // Introduce failure by calling begin again before checking fence
354 vkResetCommandBuffer(cmdBuffer.obj());
355
356 msgType = m_errorMonitor->GetState(&msgString);
357 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
358 if (!strstr(msgString.c_str(),"Resetting CB")) {
359 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
360 }
361}
362
363TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
364{
365 vk_testing::Fence testFence;
366 VK_DBG_MSG_TYPE msgType;
367 std::string msgString;
368
369 VkFenceCreateInfo fenceInfo = {};
370 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
371 fenceInfo.pNext = NULL;
372 fenceInfo.flags = 0;
373
374 ASSERT_NO_FATAL_FAILURE(InitState());
375 ASSERT_NO_FATAL_FAILURE(InitViewport());
376 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
377
378 VkCommandBufferObj cmdBuffer(m_device);
379 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
380
381 BeginCommandBuffer(cmdBuffer);
382 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
383 EndCommandBuffer(cmdBuffer);
384
385 testFence.init(*m_device, fenceInfo);
386
387 // Bypass framework since it does the waits automatically
388 VkResult err = VK_SUCCESS;
389 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
390 ASSERT_VK_SUCCESS( err );
391
392 m_errorMonitor->ClearState();
393 // Introduce failure by calling begin again before checking fence
394 BeginCommandBuffer(cmdBuffer);
395
396 msgType = m_errorMonitor->GetState(&msgString);
397 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
398 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
399 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
400 }
401}
402
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500403TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
404{
405 VK_DBG_MSG_TYPE msgType;
406 std::string msgString;
407 VkResult err;
408
409 ASSERT_NO_FATAL_FAILURE(InitState());
410 m_errorMonitor->ClearState();
411
412 // Create an image, allocate memory, free it, and then try to bind it
413 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500414 VkDeviceMemory mem;
415 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500416
417 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
418 const int32_t tex_width = 32;
419 const int32_t tex_height = 32;
420 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500421
422 const VkImageCreateInfo image_create_info = {
423 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
424 .pNext = NULL,
425 .imageType = VK_IMAGE_TYPE_2D,
426 .format = tex_format,
427 .extent = { tex_width, tex_height, 1 },
428 .mipLevels = 1,
429 .arraySize = 1,
430 .samples = 1,
431 .tiling = VK_IMAGE_TILING_LINEAR,
432 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
433 .flags = 0,
434 };
435 VkMemoryAllocInfo mem_alloc = {
436 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
437 .pNext = NULL,
438 .allocationSize = 0,
439 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
440 .memProps = 0,
441 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
442 };
443
444 err = vkCreateImage(m_device->device(), &image_create_info, &image);
445 ASSERT_VK_SUCCESS(err);
446
447 err = vkGetObjectInfo(m_device->device(),
448 VK_OBJECT_TYPE_IMAGE,
449 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500450 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
451 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500452 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500453 ASSERT_VK_SUCCESS(err);
454
Mark Lobodzinski23182612015-05-29 09:32:35 -0500455 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500456
457 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500458 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500459 ASSERT_VK_SUCCESS(err);
460
461 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500462 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500463 ASSERT_VK_SUCCESS(err);
464
465 // Map memory as if to initialize the image
466 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500467 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500468
469 msgType = m_errorMonitor->GetState(&msgString);
470 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to map memory not visible to CPU";
471 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
472 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
473 }
474}
475
476TEST_F(VkLayerTest, BindInvalidMemory)
477{
478 VK_DBG_MSG_TYPE msgType;
479 std::string msgString;
480 VkResult err;
481
482 ASSERT_NO_FATAL_FAILURE(InitState());
483 m_errorMonitor->ClearState();
484
485 // Create an image, allocate memory, free it, and then try to bind it
486 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500487 VkDeviceMemory mem;
488 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500489
490 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
491 const int32_t tex_width = 32;
492 const int32_t tex_height = 32;
493 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500494
495 const VkImageCreateInfo image_create_info = {
496 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
497 .pNext = NULL,
498 .imageType = VK_IMAGE_TYPE_2D,
499 .format = tex_format,
500 .extent = { tex_width, tex_height, 1 },
501 .mipLevels = 1,
502 .arraySize = 1,
503 .samples = 1,
504 .tiling = VK_IMAGE_TILING_LINEAR,
505 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
506 .flags = 0,
507 };
508 VkMemoryAllocInfo mem_alloc = {
509 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
510 .pNext = NULL,
511 .allocationSize = 0,
512 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
513 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
514 };
515
516 err = vkCreateImage(m_device->device(), &image_create_info, &image);
517 ASSERT_VK_SUCCESS(err);
518
519 err = vkGetObjectInfo(m_device->device(),
520 VK_OBJECT_TYPE_IMAGE,
521 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500522 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
523 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500524 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500525 ASSERT_VK_SUCCESS(err);
526
Mark Lobodzinski23182612015-05-29 09:32:35 -0500527 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500528
529 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500530 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500531 ASSERT_VK_SUCCESS(err);
532
533 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500534 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500535 ASSERT_VK_SUCCESS(err);
536
537 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500538 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500539 ASSERT_VK_SUCCESS(err);
540
541 msgType = m_errorMonitor->GetState(&msgString);
542 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to bind a freed memory object";
543 if (!strstr(msgString.c_str(),"Unable to set object")) {
544 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
545 }
546}
547
548TEST_F(VkLayerTest, FreeBoundMemory)
549{
550 VK_DBG_MSG_TYPE msgType;
551 std::string msgString;
552 VkResult err;
553
554 ASSERT_NO_FATAL_FAILURE(InitState());
555 m_errorMonitor->ClearState();
556
557 // Create an image, allocate memory, free it, and then try to bind it
558 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500559 VkDeviceMemory mem;
560 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500561
562 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
563 const int32_t tex_width = 32;
564 const int32_t tex_height = 32;
565 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500566
567 const VkImageCreateInfo image_create_info = {
568 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
569 .pNext = NULL,
570 .imageType = VK_IMAGE_TYPE_2D,
571 .format = tex_format,
572 .extent = { tex_width, tex_height, 1 },
573 .mipLevels = 1,
574 .arraySize = 1,
575 .samples = 1,
576 .tiling = VK_IMAGE_TILING_LINEAR,
577 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
578 .flags = 0,
579 };
580 VkMemoryAllocInfo mem_alloc = {
581 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
582 .pNext = NULL,
583 .allocationSize = 0,
584 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
585 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
586 };
587
588 err = vkCreateImage(m_device->device(), &image_create_info, &image);
589 ASSERT_VK_SUCCESS(err);
590
591 err = vkGetObjectInfo(m_device->device(),
592 VK_OBJECT_TYPE_IMAGE,
593 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500594 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
595 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500596 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500597 ASSERT_VK_SUCCESS(err);
598
Mark Lobodzinski23182612015-05-29 09:32:35 -0500599 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500600
601 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500602 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500603 ASSERT_VK_SUCCESS(err);
604
605 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500606 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500607 ASSERT_VK_SUCCESS(err);
608
609 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500610 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500611 ASSERT_VK_SUCCESS(err);
612
613 msgType = m_errorMonitor->GetState(&msgString);
614 ASSERT_EQ(msgType, VK_DBG_MSG_WARNING) << "Did not receive an warning while tring to free bound memory";
615 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
616 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
617 }
618}
619
620
621TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
622{
623 VK_DBG_MSG_TYPE msgType;
624 std::string msgString;
625 VkResult err;
626
627 ASSERT_NO_FATAL_FAILURE(InitState());
628 m_errorMonitor->ClearState();
629
630 // Create an image object, allocate memory, destroy the object and then try to bind it
631 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500632 VkDeviceMemory mem;
633 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500634
635 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
636 const int32_t tex_width = 32;
637 const int32_t tex_height = 32;
638 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500639
640 const VkImageCreateInfo image_create_info = {
641 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
642 .pNext = NULL,
643 .imageType = VK_IMAGE_TYPE_2D,
644 .format = tex_format,
645 .extent = { tex_width, tex_height, 1 },
646 .mipLevels = 1,
647 .arraySize = 1,
648 .samples = 1,
649 .tiling = VK_IMAGE_TILING_LINEAR,
650 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
651 .flags = 0,
652 };
653 VkMemoryAllocInfo mem_alloc = {
654 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
655 .pNext = NULL,
656 .allocationSize = 0,
657 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
658 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
659 };
660
661 err = vkCreateImage(m_device->device(), &image_create_info, &image);
662 ASSERT_VK_SUCCESS(err);
663
664 err = vkGetObjectInfo(m_device->device(),
665 VK_OBJECT_TYPE_IMAGE,
666 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500667 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
668 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500669 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500670 ASSERT_VK_SUCCESS(err);
671
Mark Lobodzinski23182612015-05-29 09:32:35 -0500672 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500673
674 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500675 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500676 ASSERT_VK_SUCCESS(err);
677
678 // Introduce validation failure, destroy Image object before binding
679 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
680 ASSERT_VK_SUCCESS(err);
681
682 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500683 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500684 ASSERT_VK_SUCCESS(err);
685
686 msgType = m_errorMonitor->GetState(&msgString);
687 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while binding memory to a destroyed object";
688 if (!strstr(msgString.c_str(),"Unable to set object")) {
689 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
690 }
691}
692
Tony Barbour8508b8e2015-04-09 10:48:04 -0600693TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600694{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600695 vk_testing::Fence testFence;
696 VK_DBG_MSG_TYPE msgType;
Tony Barbour30486ea2015-04-07 13:44:53 -0600697 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600698
699 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600700 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
701 fenceInfo.pNext = NULL;
702 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600703
Tony Barbour30486ea2015-04-07 13:44:53 -0600704 ASSERT_NO_FATAL_FAILURE(InitState());
705 ASSERT_NO_FATAL_FAILURE(InitViewport());
706 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
707
Tony Barbour01999182015-04-09 12:58:51 -0600708 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600709 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
710
Tony Barbour8508b8e2015-04-09 10:48:04 -0600711 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600712 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600713 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600714
715 testFence.init(*m_device, fenceInfo);
716 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600717 cmdBuffer.QueueCommandBuffer(testFence.obj());
Tony Barbour30486ea2015-04-07 13:44:53 -0600718 msgType = m_errorMonitor->GetState(&msgString);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600719 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
720 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500721 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600722 }
723
724}
725
726TEST_F(VkLayerTest, ResetUnsignaledFence)
727{
728 vk_testing::Fence testFence;
729 VK_DBG_MSG_TYPE msgType;
730 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600731 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600732 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
733 fenceInfo.pNext = NULL;
734
Tony Barbour8508b8e2015-04-09 10:48:04 -0600735 ASSERT_NO_FATAL_FAILURE(InitState());
736 testFence.init(*m_device, fenceInfo);
737 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600738 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600739 vkResetFences(m_device->device(), 1, fences);
740 msgType = m_errorMonitor->GetState(&msgString);
741 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 -0600742 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500743 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600744 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600745
746}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600747#endif
748#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600749TEST_F(VkLayerTest, WaitForUnsubmittedFence)
750{
751 vk_testing::Fence testFence;
752 VK_DBG_MSG_TYPE msgType;
753 std::string msgString;
754 VkFenceCreateInfo fenceInfo = {};
755 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
756 fenceInfo.pNext = NULL;
757
Tony Barbour54cdd192015-04-22 15:12:07 -0600758 ASSERT_NO_FATAL_FAILURE(InitState());
759 testFence.init(*m_device, fenceInfo);
760 m_errorMonitor->ClearState();
761 vkGetFenceStatus(m_device->device(),testFence.obj());
762 msgType = m_errorMonitor->GetState(&msgString);
763 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error asking for status of unsubmitted fence";
764 if (!strstr(msgString.c_str(),"Status Requested for Unsubmitted Fence")) {
765 FAIL() << "Error received was not Status Requested for Unsubmitted Fence";
766 }
767
768 VkFence fences[1] = {testFence.obj()};
769 m_errorMonitor->ClearState();
770 vkWaitForFences(m_device->device(), 1, fences, VK_TRUE, 0);
771 msgType = m_errorMonitor->GetState(&msgString);
772 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error for waiting for unsubmitted fence";
773 if (!strstr(msgString.c_str(),"Waiting for Unsubmitted Fence")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500774 FAIL() << "Error received was not 'Waiting for Unsubmitted Fence'";
Tony Barbour54cdd192015-04-22 15:12:07 -0600775 }
776}
777
Tony Barbourdb686622015-05-06 09:35:56 -0600778TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
779{
780 VkEventCreateInfo event_info;
781 VkEvent event;
782 VkMemoryRequirements mem_req;
783 size_t data_size = sizeof(mem_req);
784 VK_DBG_MSG_TYPE msgType;
785 std::string msgString;
786 VkResult err;
787
788 ASSERT_NO_FATAL_FAILURE(InitState());
789 memset(&event_info, 0, sizeof(event_info));
790 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
791
792 err = vkCreateEvent(device(), &event_info, &event);
793 ASSERT_VK_SUCCESS(err);
794 m_errorMonitor->ClearState();
795 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
796 &data_size, &mem_req);
797 msgType = m_errorMonitor->GetState(&msgString);
798 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from mismatched types in vkGetObjectInfo";
799 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500800 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600801 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500802}
Tony Barbourdb686622015-05-06 09:35:56 -0600803
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500804TEST_F(VkLayerTest, RasterStateNotBound)
805{
806 VK_DBG_MSG_TYPE msgType;
807 std::string msgString;
808
809 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
810
811 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
812
813 msgType = m_errorMonitor->GetState(&msgString);
814 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
815 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
816 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
817 }
818}
819
820TEST_F(VkLayerTest, ViewportStateNotBound)
821{
822 VK_DBG_MSG_TYPE msgType;
823 std::string msgString;
824 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
825
826 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
827
828 msgType = m_errorMonitor->GetState(&msgString);
829 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
830 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
831 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
832 }
833}
834
835TEST_F(VkLayerTest, ColorBlendStateNotBound)
836{
837 VK_DBG_MSG_TYPE msgType;
838 std::string msgString;
839
840 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
841
842 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
843
844 msgType = m_errorMonitor->GetState(&msgString);
845 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
846 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
847 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
848 }
849}
850
851TEST_F(VkLayerTest, DepthStencilStateNotBound)
852{
853 VK_DBG_MSG_TYPE msgType;
854 std::string msgString;
855
856 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
857
858 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
859
860 msgType = m_errorMonitor->GetState(&msgString);
861 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
862 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
863 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
864 }
Tony Barbourdb686622015-05-06 09:35:56 -0600865}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600866#endif
867#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600868TEST_F(VkLayerTest, PipelineNotBound)
869{
870 // Initiate Draw w/o a PSO bound
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600871 VK_DBG_MSG_TYPE msgType;
872 std::string msgString;
873
874 ASSERT_NO_FATAL_FAILURE(InitState());
875 m_errorMonitor->ClearState();
876 VkCommandBufferObj cmdBuffer(m_device);
877 BeginCommandBuffer(cmdBuffer);
878 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
879 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
880 msgType = m_errorMonitor->GetState(&msgString);
881 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
882 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
883 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
884 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600885}
886
887TEST_F(VkLayerTest, InvalidDescriptorPool)
888{
889 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
890 // The DS check for this is after driver has been called to validate DS internal data struct
891 // Attempt to clear DS Pool with bad object
892/* VK_DBG_MSG_TYPE msgType;
893 std::string msgString;
894 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
895 vkResetDescriptorPool(device(), badPool);
896
897 msgType = m_errorMonitor->GetState(&msgString);
898 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
899 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
900 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
901 }*/
902}
903
904TEST_F(VkLayerTest, InvalidDescriptorSet)
905{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600906 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
907 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600908 // Create a valid cmd buffer
909 // call vkCmdBindDescriptorSets w/ false DS
910}
911
912TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
913{
914 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
915 // The DS check for this is after driver has been called to validate DS internal data struct
916}
917
918TEST_F(VkLayerTest, InvalidPipeline)
919{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600920 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
921 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600922 // Create a valid cmd buffer
923 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600924 VK_DBG_MSG_TYPE msgType;
925 std::string msgString;
926
927 ASSERT_NO_FATAL_FAILURE(InitState());
928 m_errorMonitor->ClearState();
929 VkCommandBufferObj cmdBuffer(m_device);
930 BeginCommandBuffer(cmdBuffer);
931 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
932 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
933 msgType = m_errorMonitor->GetState(&msgString);
934 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
935 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
936 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
937 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600938}
939
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600940TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600941{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600942 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
943 VK_DBG_MSG_TYPE msgType;
944 std::string msgString;
945 VkResult err;
946
947 ASSERT_NO_FATAL_FAILURE(InitState());
948 m_errorMonitor->ClearState();
949 VkCommandBufferObj cmdBuffer(m_device);
950 const VkDescriptorTypeCount ds_type_count = {
951 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
952 .count = 1,
953 };
954 const VkDescriptorPoolCreateInfo ds_pool_ci = {
955 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
956 .pNext = NULL,
957 .count = 1,
958 .pTypeCount = &ds_type_count,
959 };
960 VkDescriptorPool ds_pool;
961 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
962 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600963
964 const VkDescriptorSetLayoutBinding dsl_binding = {
965 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +0800966 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600967 .stageFlags = VK_SHADER_STAGE_ALL,
968 .pImmutableSamplers = NULL,
969 };
970
971 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
972 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
973 .pNext = NULL,
974 .count = 1,
975 .pBinding = &dsl_binding,
976 };
977 VkDescriptorSetLayout ds_layout;
978 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
979 ASSERT_VK_SUCCESS(err);
980
981 VkDescriptorSet descriptorSet;
982 uint32_t ds_count = 0;
983 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
984 ASSERT_VK_SUCCESS(err);
985
986 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
987 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
988 .pNext = NULL,
989 .descriptorSetCount = 1,
990 .pSetLayouts = &ds_layout,
991 };
992
993 VkPipelineLayout pipeline_layout;
994 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
995 ASSERT_VK_SUCCESS(err);
996
997 size_t shader_len = strlen(bindStateVertShaderText);
998 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
999 void* pCode = malloc(codeSize);
1000
1001 /* try version 0 first: VkShaderStage followed by GLSL */
1002 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1003 ((uint32_t *) pCode)[1] = 0;
1004 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1005 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1006
1007 const VkShaderCreateInfo vs_ci = {
1008 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1009 .pNext = NULL,
1010 .codeSize = codeSize,
1011 .pCode = pCode,
1012 .flags = 0,
1013 };
1014 VkShader vs;
1015 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1016 ASSERT_VK_SUCCESS(err);
1017
1018 const VkPipelineShader vs_pipe_shader = {
1019 .stage = VK_SHADER_STAGE_VERTEX,
1020 .shader = vs,
1021 .linkConstBufferCount = 0,
1022 .pLinkConstBufferInfo = NULL,
1023 .pSpecializationInfo = NULL,
1024 };
1025 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1026 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1027 .pNext = NULL,
1028 .shader = vs_pipe_shader,
1029 };
1030 const VkGraphicsPipelineCreateInfo gp_ci = {
1031 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1032 .pNext = &pipe_vs_ci,
1033 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1034 .layout = pipeline_layout,
1035 };
1036
1037 VkPipeline pipeline;
1038 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1039 ASSERT_VK_SUCCESS(err);
1040
1041 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1042 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1043
1044 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1045 m_device->get_device_queue();
1046 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1047
1048 msgType = m_errorMonitor->GetState(&msgString);
1049 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1050 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1051 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1052 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001053}
1054
1055TEST_F(VkLayerTest, InvalidDynamicStateObject)
1056{
1057 // Create a valid cmd buffer
1058 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001059 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1060 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001061}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001062
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001063TEST_F(VkLayerTest, VtxBufferBadIndex)
1064{
1065 // Bind VBO out-of-bounds for given PSO
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001066 VK_DBG_MSG_TYPE msgType;
1067 std::string msgString;
1068 VkResult err;
1069
1070 ASSERT_NO_FATAL_FAILURE(InitState());
1071 m_errorMonitor->ClearState();
1072 VkCommandBufferObj cmdBuffer(m_device);
1073 const VkDescriptorTypeCount ds_type_count = {
1074 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1075 .count = 1,
1076 };
1077 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1078 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1079 .pNext = NULL,
1080 .count = 1,
1081 .pTypeCount = &ds_type_count,
1082 };
1083 VkDescriptorPool ds_pool;
1084 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1085 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001086
1087 const VkDescriptorSetLayoutBinding dsl_binding = {
1088 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001089 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001090 .stageFlags = VK_SHADER_STAGE_ALL,
1091 .pImmutableSamplers = NULL,
1092 };
1093
1094 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1095 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1096 .pNext = NULL,
1097 .count = 1,
1098 .pBinding = &dsl_binding,
1099 };
1100 VkDescriptorSetLayout ds_layout;
1101 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1102 ASSERT_VK_SUCCESS(err);
1103
1104 VkDescriptorSet descriptorSet;
1105 uint32_t ds_count = 0;
1106 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1107 ASSERT_VK_SUCCESS(err);
1108
1109 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1110 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1111 .pNext = NULL,
1112 .descriptorSetCount = 1,
1113 .pSetLayouts = &ds_layout,
1114 };
1115
1116 VkPipelineLayout pipeline_layout;
1117 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1118 ASSERT_VK_SUCCESS(err);
1119
1120 size_t shader_len = strlen(bindStateVertShaderText);
1121 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1122 void* pCode = malloc(codeSize);
1123
1124 /* try version 0 first: VkShaderStage followed by GLSL */
1125 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1126 ((uint32_t *) pCode)[1] = 0;
1127 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1128 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1129
1130 const VkShaderCreateInfo vs_ci = {
1131 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1132 .pNext = NULL,
1133 .codeSize = codeSize,
1134 .pCode = pCode,
1135 .flags = 0,
1136 };
1137 VkShader vs;
1138 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1139
1140 const VkPipelineShader vs_pipe_shader = {
1141 .stage = VK_SHADER_STAGE_VERTEX,
1142 .shader = vs,
1143 .linkConstBufferCount = 0,
1144 .pLinkConstBufferInfo = NULL,
1145 .pSpecializationInfo = NULL,
1146 };
1147 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1148 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1149 .pNext = NULL,
1150 .shader = vs_pipe_shader,
1151 };
1152 const VkGraphicsPipelineCreateInfo gp_ci = {
1153 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1154 .pNext = &pipe_vs_ci,
1155 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1156 .layout = pipeline_layout,
1157 };
1158
1159 VkPipeline pipeline;
1160 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1161 ASSERT_VK_SUCCESS(err);
1162
1163 err= cmdBuffer.BeginCommandBuffer();
1164 ASSERT_VK_SUCCESS(err);
1165 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1166 // Should error before calling to driver so don't care about actual data
1167 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1168
1169 msgType = m_errorMonitor->GetState(&msgString);
1170 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
1171 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1172 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1173 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001174}
1175
1176TEST_F(VkLayerTest, DSTypeMismatch)
1177{
1178 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001179 VK_DBG_MSG_TYPE msgType;
1180 std::string msgString;
1181 VkResult err;
1182
1183 ASSERT_NO_FATAL_FAILURE(InitState());
1184 m_errorMonitor->ClearState();
1185 //VkDescriptorSetObj descriptorSet(m_device);
1186 const VkDescriptorTypeCount ds_type_count = {
1187 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1188 .count = 1,
1189 };
1190 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1191 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1192 .pNext = NULL,
1193 .count = 1,
1194 .pTypeCount = &ds_type_count,
1195 };
1196 VkDescriptorPool ds_pool;
1197 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1198 ASSERT_VK_SUCCESS(err);
1199 const VkDescriptorSetLayoutBinding dsl_binding = {
1200 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001201 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001202 .stageFlags = VK_SHADER_STAGE_ALL,
1203 .pImmutableSamplers = NULL,
1204 };
1205
1206 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1207 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1208 .pNext = NULL,
1209 .count = 1,
1210 .pBinding = &dsl_binding,
1211 };
1212 VkDescriptorSetLayout ds_layout;
1213 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1214 ASSERT_VK_SUCCESS(err);
1215
1216 VkDescriptorSet descriptorSet;
1217 uint32_t ds_count = 0;
1218 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1219 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001220
1221 const VkSamplerCreateInfo sampler_ci = {
1222 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1223 .pNext = NULL,
1224 .magFilter = VK_TEX_FILTER_NEAREST,
1225 .minFilter = VK_TEX_FILTER_NEAREST,
1226 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1227 .addressU = VK_TEX_ADDRESS_CLAMP,
1228 .addressV = VK_TEX_ADDRESS_CLAMP,
1229 .addressW = VK_TEX_ADDRESS_CLAMP,
1230 .mipLodBias = 1.0,
1231 .maxAnisotropy = 1,
1232 .compareOp = VK_COMPARE_OP_NEVER,
1233 .minLod = 1.0,
1234 .maxLod = 1.0,
1235 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1236 };
1237 VkSampler sampler;
1238 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1239 ASSERT_VK_SUCCESS(err);
1240
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001241 VkDescriptorInfo descriptor_info;
1242 memset(&descriptor_info, 0, sizeof(descriptor_info));
1243 descriptor_info.sampler = sampler;
1244
1245 VkWriteDescriptorSet descriptor_write;
1246 memset(&descriptor_write, 0, sizeof(descriptor_write));
1247 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1248 descriptor_write.destSet = descriptorSet;
1249 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001250 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001251 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1252 descriptor_write.pDescriptors = &descriptor_info;
1253
1254 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1255
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001256 msgType = m_errorMonitor->GetState(&msgString);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001257 std::cout << msgString << "\n";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001258 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating BUFFER Descriptor w/ incorrect type of SAMPLER.";
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001259 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1260 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match overlapping binding type!'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001261 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001262}
1263
1264TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1265{
1266 // For overlapping Update, have arrayIndex exceed that of layout
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001267 VK_DBG_MSG_TYPE msgType;
1268 std::string msgString;
1269 VkResult err;
1270
1271 ASSERT_NO_FATAL_FAILURE(InitState());
1272 m_errorMonitor->ClearState();
1273 //VkDescriptorSetObj descriptorSet(m_device);
1274 const VkDescriptorTypeCount ds_type_count = {
1275 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1276 .count = 1,
1277 };
1278 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1279 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1280 .pNext = NULL,
1281 .count = 1,
1282 .pTypeCount = &ds_type_count,
1283 };
1284 VkDescriptorPool ds_pool;
1285 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1286 ASSERT_VK_SUCCESS(err);
1287 const VkDescriptorSetLayoutBinding dsl_binding = {
1288 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001289 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001290 .stageFlags = VK_SHADER_STAGE_ALL,
1291 .pImmutableSamplers = NULL,
1292 };
1293
1294 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1295 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1296 .pNext = NULL,
1297 .count = 1,
1298 .pBinding = &dsl_binding,
1299 };
1300 VkDescriptorSetLayout ds_layout;
1301 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1302 ASSERT_VK_SUCCESS(err);
1303
1304 VkDescriptorSet descriptorSet;
1305 uint32_t ds_count = 0;
1306 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1307 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001308
1309 const VkSamplerCreateInfo sampler_ci = {
1310 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1311 .pNext = NULL,
1312 .magFilter = VK_TEX_FILTER_NEAREST,
1313 .minFilter = VK_TEX_FILTER_NEAREST,
1314 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1315 .addressU = VK_TEX_ADDRESS_CLAMP,
1316 .addressV = VK_TEX_ADDRESS_CLAMP,
1317 .addressW = VK_TEX_ADDRESS_CLAMP,
1318 .mipLodBias = 1.0,
1319 .maxAnisotropy = 1,
1320 .compareOp = VK_COMPARE_OP_NEVER,
1321 .minLod = 1.0,
1322 .maxLod = 1.0,
1323 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1324 };
1325 VkSampler sampler;
1326 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1327 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001328
1329 VkDescriptorInfo descriptor_info;
1330 memset(&descriptor_info, 0, sizeof(descriptor_info));
1331 descriptor_info.sampler = sampler;
1332
1333 VkWriteDescriptorSet descriptor_write;
1334 memset(&descriptor_write, 0, sizeof(descriptor_write));
1335 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1336 descriptor_write.destSet = descriptorSet;
1337 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1338 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001339 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001340 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1341 descriptor_write.pDescriptors = &descriptor_info;
1342
1343 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1344
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001345 msgType = m_errorMonitor->GetState(&msgString);
1346 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ index out of bounds.";
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001347 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1348 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding...'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001349 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001350}
1351
1352TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1353{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001354 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
1355 VK_DBG_MSG_TYPE msgType;
1356 std::string msgString;
1357 VkResult err;
1358
1359 ASSERT_NO_FATAL_FAILURE(InitState());
1360 m_errorMonitor->ClearState();
1361 //VkDescriptorSetObj descriptorSet(m_device);
1362 const VkDescriptorTypeCount ds_type_count = {
1363 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1364 .count = 1,
1365 };
1366 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1367 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1368 .pNext = NULL,
1369 .count = 1,
1370 .pTypeCount = &ds_type_count,
1371 };
1372 VkDescriptorPool ds_pool;
1373 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1374 ASSERT_VK_SUCCESS(err);
1375 const VkDescriptorSetLayoutBinding dsl_binding = {
1376 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001377 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001378 .stageFlags = VK_SHADER_STAGE_ALL,
1379 .pImmutableSamplers = NULL,
1380 };
1381
1382 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1383 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1384 .pNext = NULL,
1385 .count = 1,
1386 .pBinding = &dsl_binding,
1387 };
1388 VkDescriptorSetLayout ds_layout;
1389 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1390 ASSERT_VK_SUCCESS(err);
1391
1392 VkDescriptorSet descriptorSet;
1393 uint32_t ds_count = 0;
1394 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1395 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001396
1397 const VkSamplerCreateInfo sampler_ci = {
1398 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1399 .pNext = NULL,
1400 .magFilter = VK_TEX_FILTER_NEAREST,
1401 .minFilter = VK_TEX_FILTER_NEAREST,
1402 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1403 .addressU = VK_TEX_ADDRESS_CLAMP,
1404 .addressV = VK_TEX_ADDRESS_CLAMP,
1405 .addressW = VK_TEX_ADDRESS_CLAMP,
1406 .mipLodBias = 1.0,
1407 .maxAnisotropy = 1,
1408 .compareOp = VK_COMPARE_OP_NEVER,
1409 .minLod = 1.0,
1410 .maxLod = 1.0,
1411 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1412 };
1413 VkSampler sampler;
1414 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1415 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001416
1417 VkDescriptorInfo descriptor_info;
1418 memset(&descriptor_info, 0, sizeof(descriptor_info));
1419 descriptor_info.sampler = sampler;
1420
1421 VkWriteDescriptorSet descriptor_write;
1422 memset(&descriptor_write, 0, sizeof(descriptor_write));
1423 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1424 descriptor_write.destSet = descriptorSet;
1425 descriptor_write.destBinding = 2;
1426 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001427 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001428 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1429 descriptor_write.pDescriptors = &descriptor_info;
1430
1431 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1432
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001433 msgType = m_errorMonitor->GetState(&msgString);
1434 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ count too large for layout.";
1435 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1436 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1437 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001438}
1439
1440TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1441{
1442 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001443 VK_DBG_MSG_TYPE msgType;
1444 std::string msgString;
1445 VkResult err;
1446
1447 ASSERT_NO_FATAL_FAILURE(InitState());
1448 m_errorMonitor->ClearState();
1449 //VkDescriptorSetObj descriptorSet(m_device);
1450 const VkDescriptorTypeCount ds_type_count = {
1451 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1452 .count = 1,
1453 };
1454 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1455 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1456 .pNext = NULL,
1457 .count = 1,
1458 .pTypeCount = &ds_type_count,
1459 };
1460 VkDescriptorPool ds_pool;
1461 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1462 ASSERT_VK_SUCCESS(err);
1463 const VkDescriptorSetLayoutBinding dsl_binding = {
1464 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001465 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001466 .stageFlags = VK_SHADER_STAGE_ALL,
1467 .pImmutableSamplers = NULL,
1468 };
1469
1470 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1471 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1472 .pNext = NULL,
1473 .count = 1,
1474 .pBinding = &dsl_binding,
1475 };
1476 VkDescriptorSetLayout ds_layout;
1477 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1478 ASSERT_VK_SUCCESS(err);
1479
1480 VkDescriptorSet descriptorSet;
1481 uint32_t ds_count = 0;
1482 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1483 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001484
1485 const VkSamplerCreateInfo sampler_ci = {
1486 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1487 .pNext = NULL,
1488 .magFilter = VK_TEX_FILTER_NEAREST,
1489 .minFilter = VK_TEX_FILTER_NEAREST,
1490 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1491 .addressU = VK_TEX_ADDRESS_CLAMP,
1492 .addressV = VK_TEX_ADDRESS_CLAMP,
1493 .addressW = VK_TEX_ADDRESS_CLAMP,
1494 .mipLodBias = 1.0,
1495 .maxAnisotropy = 1,
1496 .compareOp = VK_COMPARE_OP_NEVER,
1497 .minLod = 1.0,
1498 .maxLod = 1.0,
1499 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1500 };
1501 VkSampler sampler;
1502 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1503 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001504
1505
1506 VkDescriptorInfo descriptor_info;
1507 memset(&descriptor_info, 0, sizeof(descriptor_info));
1508 descriptor_info.sampler = sampler;
1509
1510 VkWriteDescriptorSet descriptor_write;
1511 memset(&descriptor_write, 0, sizeof(descriptor_write));
1512 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1513 descriptor_write.destSet = descriptorSet;
1514 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001515 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001516 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1517 descriptor_write.pDescriptors = &descriptor_info;
1518
1519 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1520
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001521 msgType = m_errorMonitor->GetState(&msgString);
1522 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ invalid struct type.";
1523 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1524 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1525 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001526}
1527
1528TEST_F(VkLayerTest, NumSamplesMismatch)
1529{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001530 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1531 VK_DBG_MSG_TYPE msgType;
1532 std::string msgString;
1533 VkResult err;
1534
1535 ASSERT_NO_FATAL_FAILURE(InitState());
1536 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1537 m_errorMonitor->ClearState();
1538 VkCommandBufferObj cmdBuffer(m_device);
1539 const VkDescriptorTypeCount ds_type_count = {
1540 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1541 .count = 1,
1542 };
1543 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1544 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1545 .pNext = NULL,
1546 .count = 1,
1547 .pTypeCount = &ds_type_count,
1548 };
1549 VkDescriptorPool ds_pool;
1550 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1551 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001552
1553 const VkDescriptorSetLayoutBinding dsl_binding = {
1554 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001555 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001556 .stageFlags = VK_SHADER_STAGE_ALL,
1557 .pImmutableSamplers = NULL,
1558 };
1559
1560 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1561 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1562 .pNext = NULL,
1563 .count = 1,
1564 .pBinding = &dsl_binding,
1565 };
1566 VkDescriptorSetLayout ds_layout;
1567 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1568 ASSERT_VK_SUCCESS(err);
1569
1570 VkDescriptorSet descriptorSet;
1571 uint32_t ds_count = 0;
1572 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1573 ASSERT_VK_SUCCESS(err);
1574
1575 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1576 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1577 .pNext = NULL,
Tony Barbourd1e95582015-06-03 12:30:49 -06001578 .samples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001579 .multisampleEnable = 1,
1580 .sampleShadingEnable = 0,
1581 .minSampleShading = 1.0,
1582 .sampleMask = 15,
1583 };
1584
1585 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1586 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1587 .pNext = NULL,
1588 .descriptorSetCount = 1,
1589 .pSetLayouts = &ds_layout,
1590 };
1591
1592 VkPipelineLayout pipeline_layout;
1593 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1594 ASSERT_VK_SUCCESS(err);
1595
1596 size_t shader_len = strlen(bindStateVertShaderText);
1597 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1598 void* pCode = malloc(codeSize);
1599
1600 /* try version 0 first: VkShaderStage followed by GLSL */
1601 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1602 ((uint32_t *) pCode)[1] = 0;
1603 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1604 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1605
1606 const VkShaderCreateInfo vs_ci = {
1607 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1608 .pNext = NULL,
1609 .codeSize = codeSize,
1610 .pCode = pCode,
1611 .flags = 0,
1612 };
1613 VkShader vs;
1614 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1615 ASSERT_VK_SUCCESS(err);
1616
1617 const VkPipelineShader vs_pipe_shader = {
1618 .stage = VK_SHADER_STAGE_VERTEX,
1619 .shader = vs,
1620 .linkConstBufferCount = 0,
1621 .pLinkConstBufferInfo = NULL,
1622 .pSpecializationInfo = NULL,
1623 };
1624 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1625 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1626 .pNext = &pipe_ms_state_ci,
1627 .shader = vs_pipe_shader,
1628 };
1629 const VkGraphicsPipelineCreateInfo gp_ci = {
1630 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1631 .pNext = &pipe_vs_ci,
1632 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1633 .layout = pipeline_layout,
1634 };
1635
1636 VkPipeline pipeline;
1637 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1638 ASSERT_VK_SUCCESS(err);
1639
1640 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1641 BeginCommandBuffer(cmdBuffer);
1642 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1643
1644 msgType = m_errorMonitor->GetState(&msgString);
1645 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
1646 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1647 FAIL() << "Error received was not 'Num samples mismatch!...'";
1648 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001649}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001650#endif
1651#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001652#if GTEST_IS_THREADSAFE
1653struct thread_data_struct {
1654 VkCmdBuffer cmdBuffer;
1655 VkEvent event;
1656 bool bailout;
1657};
1658
1659extern "C" void *AddToCommandBuffer(void *arg)
1660{
1661 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1662 std::string msgString;
1663
1664 for (int i = 0; i<10000; i++) {
1665 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1666 if (data->bailout) {
1667 break;
1668 }
1669 }
1670 return NULL;
1671}
1672
1673TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1674{
1675 VK_DBG_MSG_TYPE msgType;
1676 std::string msgString;
1677 pthread_t thread;
1678 pthread_attr_t thread_attr;
1679
1680 ASSERT_NO_FATAL_FAILURE(InitState());
1681 ASSERT_NO_FATAL_FAILURE(InitViewport());
1682 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1683
1684 VkCommandBufferObj cmdBuffer(m_device);
1685
1686 m_errorMonitor->ClearState();
1687 pthread_attr_init(&thread_attr);
1688 BeginCommandBuffer(cmdBuffer);
1689
1690 VkEventCreateInfo event_info;
1691 VkEvent event;
1692 VkMemoryRequirements mem_req;
1693 size_t data_size = sizeof(mem_req);
1694 VkResult err;
1695
1696 memset(&event_info, 0, sizeof(event_info));
1697 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1698
1699 err = vkCreateEvent(device(), &event_info, &event);
1700 ASSERT_VK_SUCCESS(err);
1701
1702 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1703 &data_size, &mem_req);
1704 ASSERT_VK_SUCCESS(err);
1705
1706 VkMemoryAllocInfo mem_info;
1707 VkDeviceMemory event_mem;
1708
1709 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1710
1711 memset(&mem_info, 0, sizeof(mem_info));
1712 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1713 mem_info.allocationSize = mem_req.size;
1714 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1715 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1716 err = vkAllocMemory(device(), &mem_info, &event_mem);
1717 ASSERT_VK_SUCCESS(err);
1718
Mark Lobodzinski23182612015-05-29 09:32:35 -05001719 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001720 ASSERT_VK_SUCCESS(err);
1721
1722 err = vkResetEvent(device(), event);
1723 ASSERT_VK_SUCCESS(err);
1724
1725 struct thread_data_struct data;
1726 data.cmdBuffer = cmdBuffer.obj();
1727 data.event = event;
1728 data.bailout = false;
1729 m_errorMonitor->SetBailout(&data.bailout);
1730 // Add many entries to command buffer from another thread.
1731 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1732 // Add many entries to command buffer from this thread at the same time.
1733 AddToCommandBuffer(&data);
1734 pthread_join(thread, NULL);
1735 EndCommandBuffer(cmdBuffer);
1736
1737 msgType = m_errorMonitor->GetState(&msgString);
1738 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using one VkCommandBufferObj in two threads";
1739 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001740 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001741 }
1742
1743}
1744#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001745#endif
Tony Barbour30486ea2015-04-07 13:44:53 -06001746int main(int argc, char **argv) {
1747 int result;
1748
1749 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06001750 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06001751
1752 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
1753
1754 result = RUN_ALL_TESTS();
1755
Tony Barbour01999182015-04-09 12:58:51 -06001756 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06001757 return result;
1758}