blob: 1269e8268ed19b8a8173e36902642c60d010773e [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
Chris Forbes5af3bf22015-05-25 11:13:08 +120015#define SHADER_CHECKER_TESTS 1
Tobin Ehlis57e6a612015-05-26 16:11:58 -060016
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050017//--------------------------------------------------------------------------------------
18// Mesh and VertexFormat Data
19//--------------------------------------------------------------------------------------
20struct Vertex
21{
22 float posX, posY, posZ, posW; // Position data
23 float r, g, b, a; // Color
24};
25
26#define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
27
28typedef enum _BsoFailSelect {
29 BsoFailNone = 0x00000000,
30 BsoFailRaster = 0x00000001,
31 BsoFailViewport = 0x00000002,
32 BsoFailColorBlend = 0x00000004,
33 BsoFailDepthStencil = 0x00000008,
34} BsoFailSelect;
35
36struct vktriangle_vs_uniform {
37 // Must start with MVP
38 float mvp[4][4];
39 float position[3][4];
40 float color[3][4];
41};
42
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050043static const char bindStateVertShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050044 "#version 130\n"
45 "vec2 vertices[3];\n"
46 "void main() {\n"
47 " vertices[0] = vec2(-1.0, -1.0);\n"
48 " vertices[1] = vec2( 1.0, -1.0);\n"
49 " vertices[2] = vec2( 0.0, 1.0);\n"
50 " gl_Position = vec4(vertices[gl_VertexID % 3], 0.0, 1.0);\n"
51 "}\n";
52
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050053static const char bindStateFragShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050054 "#version 130\n"
55 "void main() {\n"
56 " gl_FragColor = vec4(0,1,0,1);\n"
57 "}\n";
58
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060059void VKAPI myDbgFunc(
60 VK_DBG_MSG_TYPE msgType,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060061 VkValidationLevel validationLevel,
Mike Stroyan230e6252015-04-17 12:36:38 -060062 VkObject srcObject,
Tony Barbour30486ea2015-04-07 13:44:53 -060063 size_t location,
64 int32_t msgCode,
65 const char* pMsg,
66 void* pUserData);
67
68class ErrorMonitor {
69public:
Tony Barbour0c1bdc62015-04-29 17:34:29 -060070 ErrorMonitor()
Tony Barbour30486ea2015-04-07 13:44:53 -060071 {
Mike Stroyan09aae812015-05-12 16:00:45 -060072 pthread_mutexattr_t attr;
73 pthread_mutexattr_init(&attr);
74 pthread_mutex_init(&m_mutex, &attr);
75 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060076 m_msgType = VK_DBG_MSG_UNKNOWN;
Mike Stroyan09aae812015-05-12 16:00:45 -060077 m_bailout = NULL;
78 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060079 }
80 void ClearState()
81 {
Mike Stroyan09aae812015-05-12 16:00:45 -060082 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060083 m_msgType = VK_DBG_MSG_UNKNOWN;
Tony Barbour30486ea2015-04-07 13:44:53 -060084 m_msgString.clear();
Mike Stroyan09aae812015-05-12 16:00:45 -060085 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060086 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060087 VK_DBG_MSG_TYPE GetState(std::string *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060088 {
Mike Stroyan09aae812015-05-12 16:00:45 -060089 pthread_mutex_lock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060090 *msgString = m_msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -060091 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060092 return m_msgType;
93 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060094 void SetState(VK_DBG_MSG_TYPE msgType, const char *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060095 {
Mike Stroyan09aae812015-05-12 16:00:45 -060096 pthread_mutex_lock(&m_mutex);
97 if (m_bailout != NULL) {
98 *m_bailout = true;
99 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600100 m_msgType = msgType;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600101 m_msgString.reserve(strlen(msgString));
102 m_msgString = msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -0600103 pthread_mutex_unlock(&m_mutex);
104 }
105 void SetBailout(bool *bailout)
106 {
107 m_bailout = bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600108 }
109
110private:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600111 VK_DBG_MSG_TYPE m_msgType;
Mike Stroyan09aae812015-05-12 16:00:45 -0600112 std::string m_msgString;
113 pthread_mutex_t m_mutex;
114 bool* m_bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600115};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500116
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600117void VKAPI myDbgFunc(
Mike Stroyan230e6252015-04-17 12:36:38 -0600118 VK_DBG_MSG_TYPE msgType,
119 VkValidationLevel validationLevel,
120 VkObject srcObject,
Tony Barbour30486ea2015-04-07 13:44:53 -0600121 size_t location,
122 int32_t msgCode,
123 const char* pMsg,
124 void* pUserData)
125{
Tony Barbour8508b8e2015-04-09 10:48:04 -0600126 if (msgType == VK_DBG_MSG_WARNING || msgType == VK_DBG_MSG_ERROR) {
127 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
128 errMonitor->SetState(msgType, pMsg);
129 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600130}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500131
Tony Barbour01999182015-04-09 12:58:51 -0600132class VkLayerTest : public VkRenderFramework
Tony Barbour30486ea2015-04-07 13:44:53 -0600133{
134public:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600135 VkResult BeginCommandBuffer(VkCommandBufferObj &cmdBuffer);
136 VkResult EndCommandBuffer(VkCommandBufferObj &cmdBuffer);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500137 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
138 void GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask);
Tony Barbour30486ea2015-04-07 13:44:53 -0600139
140protected:
Tony Barbour01999182015-04-09 12:58:51 -0600141 VkMemoryRefManager m_memoryRefManager;
142 ErrorMonitor *m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600143
144 virtual void SetUp() {
Chris Forbesd0f3f442015-05-25 11:13:00 +1200145 const char *extension_names[] = {"MemTracker", "ObjectTracker", "Threading", "DrawState", "ShaderChecker"};
Mike Stroyan09aae812015-05-12 16:00:45 -0600146 const std::vector<const char *> extensions(extension_names,
147 extension_names + sizeof(extension_names)/sizeof(extension_names[0]));
Tony Barbour950ebc02015-04-23 12:55:36 -0600148
149 size_t extSize = sizeof(uint32_t);
150 uint32_t extCount = 0;
Tony Barbour04ada4a2015-04-23 15:28:27 -0600151 VkResult U_ASSERT_ONLY err;
Tony Barbour950ebc02015-04-23 12:55:36 -0600152 err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount);
153 assert(!err);
154
155 VkExtensionProperties extProp;
156 extSize = sizeof(VkExtensionProperties);
157 bool32_t extFound;
158
Tony Barbour04ada4a2015-04-23 15:28:27 -0600159 for (uint32_t i = 0; i < extensions.size(); i++) {
Tony Barbour950ebc02015-04-23 12:55:36 -0600160 extFound = 0;
161 for (uint32_t j = 0; j < extCount; j++) {
162 err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_PROPERTIES, j, &extSize, &extProp);
Tony Barbour04ada4a2015-04-23 15:28:27 -0600163 assert(!err);
164 if (!strcmp(extensions[i], extProp.extName)) {
Tony Barbour950ebc02015-04-23 12:55:36 -0600165 extFound = 1;
166 break;
167 }
168 }
Tony Barbour04ada4a2015-04-23 15:28:27 -0600169 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 -0600170 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600171
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500172 // Force layer output level to be >= WARNING so that we catch those messages but ignore others
173 setLayerOptionEnum("MemTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
174 setLayerOptionEnum("ObjectTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
175 setLayerOptionEnum("ThreadingReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600176 setLayerOptionEnum("DrawStateReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Chris Forbesd0f3f442015-05-25 11:13:00 +1200177 setLayerOptionEnum("ShaderCheckerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500178
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600179 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600180 this->app_info.pNext = NULL;
181 this->app_info.pAppName = "layer_tests";
182 this->app_info.appVersion = 1;
183 this->app_info.pEngineName = "unittest";
184 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600185 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600186
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600187 m_errorMonitor = new ErrorMonitor;
188 InitFramework(extensions, myDbgFunc, m_errorMonitor);
189
Tony Barbour30486ea2015-04-07 13:44:53 -0600190 }
191
192 virtual void TearDown() {
193 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600194 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600195 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600196 }
197};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500198
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600199VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600200{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600201 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600202
203 result = cmdBuffer.BeginCommandBuffer();
204
205 /*
206 * For render test all drawing happens in a single render pass
207 * on a single command buffer.
208 */
Chris Forbesfe133ef2015-06-16 14:05:59 +1200209 if (VK_SUCCESS == result && renderPass()) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600210 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
211 }
212
213 return result;
214}
215
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600216VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600217{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600218 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600219
Chris Forbesfe133ef2015-06-16 14:05:59 +1200220 if (renderPass()) {
221 cmdBuffer.EndRenderPass(renderPass());
222 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600223
224 result = cmdBuffer.EndCommandBuffer();
225
226 return result;
227}
228
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500229void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
230{
231 // Create identity matrix
232 int i;
233 struct vktriangle_vs_uniform data;
234
235 glm::mat4 Projection = glm::mat4(1.0f);
236 glm::mat4 View = glm::mat4(1.0f);
237 glm::mat4 Model = glm::mat4(1.0f);
238 glm::mat4 MVP = Projection * View * Model;
239 const int matrixSize = sizeof(MVP);
240 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
241
242 memcpy(&data.mvp, &MVP[0][0], matrixSize);
243
244 static const Vertex tri_data[] =
245 {
246 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
247 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
248 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
249 };
250
251 for (i=0; i<3; i++) {
252 data.position[i][0] = tri_data[i].posX;
253 data.position[i][1] = tri_data[i].posY;
254 data.position[i][2] = tri_data[i].posZ;
255 data.position[i][3] = tri_data[i].posW;
256 data.color[i][0] = tri_data[i].r;
257 data.color[i][1] = tri_data[i].g;
258 data.color[i][2] = tri_data[i].b;
259 data.color[i][3] = tri_data[i].a;
260 }
261
262 ASSERT_NO_FATAL_FAILURE(InitState());
263 ASSERT_NO_FATAL_FAILURE(InitViewport());
264
265 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
266
267 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
268 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
269
270 VkPipelineObj pipelineobj(m_device);
271 pipelineobj.AddShader(&vs);
272 pipelineobj.AddShader(&ps);
273
274 VkDescriptorSetObj descriptorSet(m_device);
275 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
276
277 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
278 VkCommandBufferObj cmdBuffer(m_device);
279 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
280
281 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
282
283 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
284
285 // render triangle
286 cmdBuffer.Draw(0, 3, 0, 1);
287
288 // finalize recording of the command buffer
289 EndCommandBuffer(cmdBuffer);
290
291 cmdBuffer.QueueCommandBuffer();
292}
293
294void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
295{
296 if (m_depthStencil->Initialized()) {
297 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
298 } else {
299 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
300 }
301
302 cmdBuffer->PrepareAttachments();
303 if ((failMask & BsoFailRaster) != BsoFailRaster) {
304 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
305 }
306 if ((failMask & BsoFailViewport) != BsoFailViewport) {
307 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
308 }
309 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
310 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
311 }
312 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
313 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
314 }
315 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
316 pipelineobj.CreateVKPipeline(descriptorSet);
317 cmdBuffer->BindPipeline(pipelineobj);
318 cmdBuffer->BindDescriptorSet(descriptorSet);
319}
320
321// ********************************************************************************************************************
322// ********************************************************************************************************************
323// ********************************************************************************************************************
324// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600325#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500326TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
327{
328 vk_testing::Fence testFence;
329 VK_DBG_MSG_TYPE msgType;
330 std::string msgString;
331
332 VkFenceCreateInfo fenceInfo = {};
333 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
334 fenceInfo.pNext = NULL;
335 fenceInfo.flags = 0;
336
337 ASSERT_NO_FATAL_FAILURE(InitState());
338 ASSERT_NO_FATAL_FAILURE(InitViewport());
339 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
340
341 VkCommandBufferObj cmdBuffer(m_device);
342 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
343
344 BeginCommandBuffer(cmdBuffer);
345 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
346 EndCommandBuffer(cmdBuffer);
347
348 testFence.init(*m_device, fenceInfo);
349
350 // Bypass framework since it does the waits automatically
351 VkResult err = VK_SUCCESS;
352 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
353 ASSERT_VK_SUCCESS( err );
354
355 m_errorMonitor->ClearState();
356 // Introduce failure by calling begin again before checking fence
357 vkResetCommandBuffer(cmdBuffer.obj());
358
359 msgType = m_errorMonitor->GetState(&msgString);
360 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
361 if (!strstr(msgString.c_str(),"Resetting CB")) {
362 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
363 }
364}
365
366TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
367{
368 vk_testing::Fence testFence;
369 VK_DBG_MSG_TYPE msgType;
370 std::string msgString;
371
372 VkFenceCreateInfo fenceInfo = {};
373 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
374 fenceInfo.pNext = NULL;
375 fenceInfo.flags = 0;
376
377 ASSERT_NO_FATAL_FAILURE(InitState());
378 ASSERT_NO_FATAL_FAILURE(InitViewport());
379 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
380
381 VkCommandBufferObj cmdBuffer(m_device);
382 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
383
384 BeginCommandBuffer(cmdBuffer);
385 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
386 EndCommandBuffer(cmdBuffer);
387
388 testFence.init(*m_device, fenceInfo);
389
390 // Bypass framework since it does the waits automatically
391 VkResult err = VK_SUCCESS;
392 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
393 ASSERT_VK_SUCCESS( err );
394
395 m_errorMonitor->ClearState();
396 // Introduce failure by calling begin again before checking fence
397 BeginCommandBuffer(cmdBuffer);
398
399 msgType = m_errorMonitor->GetState(&msgString);
400 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
401 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
402 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
403 }
404}
405
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500406TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
407{
408 VK_DBG_MSG_TYPE msgType;
409 std::string msgString;
410 VkResult err;
411
412 ASSERT_NO_FATAL_FAILURE(InitState());
413 m_errorMonitor->ClearState();
414
415 // Create an image, allocate memory, free it, and then try to bind it
416 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500417 VkDeviceMemory mem;
418 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500419
420 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
421 const int32_t tex_width = 32;
422 const int32_t tex_height = 32;
423 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500424
425 const VkImageCreateInfo image_create_info = {
426 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
427 .pNext = NULL,
428 .imageType = VK_IMAGE_TYPE_2D,
429 .format = tex_format,
430 .extent = { tex_width, tex_height, 1 },
431 .mipLevels = 1,
432 .arraySize = 1,
433 .samples = 1,
434 .tiling = VK_IMAGE_TILING_LINEAR,
435 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
436 .flags = 0,
437 };
438 VkMemoryAllocInfo mem_alloc = {
439 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
440 .pNext = NULL,
441 .allocationSize = 0,
442 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
443 .memProps = 0,
444 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
445 };
446
447 err = vkCreateImage(m_device->device(), &image_create_info, &image);
448 ASSERT_VK_SUCCESS(err);
449
450 err = vkGetObjectInfo(m_device->device(),
451 VK_OBJECT_TYPE_IMAGE,
452 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500453 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
454 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500455 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500456 ASSERT_VK_SUCCESS(err);
457
Mark Lobodzinski23182612015-05-29 09:32:35 -0500458 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500459
460 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500461 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500462 ASSERT_VK_SUCCESS(err);
463
464 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500465 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500466 ASSERT_VK_SUCCESS(err);
467
468 // Map memory as if to initialize the image
469 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500470 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500471
472 msgType = m_errorMonitor->GetState(&msgString);
473 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to map memory not visible to CPU";
474 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
475 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
476 }
477}
478
479TEST_F(VkLayerTest, BindInvalidMemory)
480{
481 VK_DBG_MSG_TYPE msgType;
482 std::string msgString;
483 VkResult err;
484
485 ASSERT_NO_FATAL_FAILURE(InitState());
486 m_errorMonitor->ClearState();
487
488 // Create an image, allocate memory, free it, and then try to bind it
489 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500490 VkDeviceMemory mem;
491 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500492
493 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
494 const int32_t tex_width = 32;
495 const int32_t tex_height = 32;
496 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500497
498 const VkImageCreateInfo image_create_info = {
499 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
500 .pNext = NULL,
501 .imageType = VK_IMAGE_TYPE_2D,
502 .format = tex_format,
503 .extent = { tex_width, tex_height, 1 },
504 .mipLevels = 1,
505 .arraySize = 1,
506 .samples = 1,
507 .tiling = VK_IMAGE_TILING_LINEAR,
508 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
509 .flags = 0,
510 };
511 VkMemoryAllocInfo mem_alloc = {
512 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
513 .pNext = NULL,
514 .allocationSize = 0,
515 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
516 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
517 };
518
519 err = vkCreateImage(m_device->device(), &image_create_info, &image);
520 ASSERT_VK_SUCCESS(err);
521
522 err = vkGetObjectInfo(m_device->device(),
523 VK_OBJECT_TYPE_IMAGE,
524 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500525 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
526 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500527 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500528 ASSERT_VK_SUCCESS(err);
529
Mark Lobodzinski23182612015-05-29 09:32:35 -0500530 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500531
532 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500533 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500534 ASSERT_VK_SUCCESS(err);
535
536 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500537 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500538 ASSERT_VK_SUCCESS(err);
539
540 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500541 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500542 ASSERT_VK_SUCCESS(err);
543
544 msgType = m_errorMonitor->GetState(&msgString);
545 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to bind a freed memory object";
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500546 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500547 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
548 }
549}
550
551TEST_F(VkLayerTest, FreeBoundMemory)
552{
553 VK_DBG_MSG_TYPE msgType;
554 std::string msgString;
555 VkResult err;
556
557 ASSERT_NO_FATAL_FAILURE(InitState());
558 m_errorMonitor->ClearState();
559
560 // Create an image, allocate memory, free it, and then try to bind it
561 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500562 VkDeviceMemory mem;
563 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500564
565 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
566 const int32_t tex_width = 32;
567 const int32_t tex_height = 32;
568 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500569
570 const VkImageCreateInfo image_create_info = {
571 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
572 .pNext = NULL,
573 .imageType = VK_IMAGE_TYPE_2D,
574 .format = tex_format,
575 .extent = { tex_width, tex_height, 1 },
576 .mipLevels = 1,
577 .arraySize = 1,
578 .samples = 1,
579 .tiling = VK_IMAGE_TILING_LINEAR,
580 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
581 .flags = 0,
582 };
583 VkMemoryAllocInfo mem_alloc = {
584 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
585 .pNext = NULL,
586 .allocationSize = 0,
587 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
588 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
589 };
590
591 err = vkCreateImage(m_device->device(), &image_create_info, &image);
592 ASSERT_VK_SUCCESS(err);
593
594 err = vkGetObjectInfo(m_device->device(),
595 VK_OBJECT_TYPE_IMAGE,
596 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500597 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
598 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500599 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500600 ASSERT_VK_SUCCESS(err);
601
Mark Lobodzinski23182612015-05-29 09:32:35 -0500602 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500603
604 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500605 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500606 ASSERT_VK_SUCCESS(err);
607
608 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500609 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500610 ASSERT_VK_SUCCESS(err);
611
612 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500613 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500614 ASSERT_VK_SUCCESS(err);
615
616 msgType = m_errorMonitor->GetState(&msgString);
617 ASSERT_EQ(msgType, VK_DBG_MSG_WARNING) << "Did not receive an warning while tring to free bound memory";
618 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
619 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
620 }
621}
622
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500623TEST_F(VkLayerTest, RebindMemory)
624{
625 VK_DBG_MSG_TYPE msgType;
626 std::string msgString;
627 VkResult err;
628
629 ASSERT_NO_FATAL_FAILURE(InitState());
630 m_errorMonitor->ClearState();
631
632 // Create an image, allocate memory, free it, and then try to bind it
633 VkImage image;
634 VkDeviceMemory mem1;
635 VkDeviceMemory mem2;
636 VkMemoryRequirements mem_reqs;
637
638 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
639 const int32_t tex_width = 32;
640 const int32_t tex_height = 32;
641 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
642
643 const VkImageCreateInfo image_create_info = {
644 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
645 .pNext = NULL,
646 .imageType = VK_IMAGE_TYPE_2D,
647 .format = tex_format,
648 .extent = { tex_width, tex_height, 1 },
649 .mipLevels = 1,
650 .arraySize = 1,
651 .samples = 1,
652 .tiling = VK_IMAGE_TILING_LINEAR,
653 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
654 .flags = 0,
655 };
656 VkMemoryAllocInfo mem_alloc = {
657 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
658 .pNext = NULL,
659 .allocationSize = 0,
660 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
661 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
662 };
663
664 err = vkCreateImage(m_device->device(), &image_create_info, &image);
665 ASSERT_VK_SUCCESS(err);
666
667 err = vkGetObjectInfo(m_device->device(),
668 VK_OBJECT_TYPE_IMAGE,
669 image,
670 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
671 &mem_reqs_size,
672 &mem_reqs);
673 ASSERT_VK_SUCCESS(err);
674
675 mem_alloc.allocationSize = mem_reqs.size;
676
677 // allocate 2 memory objects
678 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
679 ASSERT_VK_SUCCESS(err);
680 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
681 ASSERT_VK_SUCCESS(err);
682
683 // Bind first memory object to Image object
684 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
685 ASSERT_VK_SUCCESS(err);
686
687 // Introduce validation failure, try to bind a different memory object to the same image object
688 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
689 ASSERT_VK_SUCCESS(err);
690
691 msgType = m_errorMonitor->GetState(&msgString);
692 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to rebind an object";
693 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
694 FAIL() << "Error received did not match expected message when rebinding memory to an object";
695 }
696}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500697
698TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
699{
700 VK_DBG_MSG_TYPE msgType;
701 std::string msgString;
702 VkResult err;
703
704 ASSERT_NO_FATAL_FAILURE(InitState());
705 m_errorMonitor->ClearState();
706
707 // Create an image object, allocate memory, destroy the object and then try to bind it
708 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500709 VkDeviceMemory mem;
710 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500711
712 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
713 const int32_t tex_width = 32;
714 const int32_t tex_height = 32;
715 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500716
717 const VkImageCreateInfo image_create_info = {
718 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
719 .pNext = NULL,
720 .imageType = VK_IMAGE_TYPE_2D,
721 .format = tex_format,
722 .extent = { tex_width, tex_height, 1 },
723 .mipLevels = 1,
724 .arraySize = 1,
725 .samples = 1,
726 .tiling = VK_IMAGE_TILING_LINEAR,
727 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
728 .flags = 0,
729 };
730 VkMemoryAllocInfo mem_alloc = {
731 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
732 .pNext = NULL,
733 .allocationSize = 0,
734 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
735 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
736 };
737
738 err = vkCreateImage(m_device->device(), &image_create_info, &image);
739 ASSERT_VK_SUCCESS(err);
740
741 err = vkGetObjectInfo(m_device->device(),
742 VK_OBJECT_TYPE_IMAGE,
743 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500744 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
745 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500746 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500747 ASSERT_VK_SUCCESS(err);
748
Mark Lobodzinski23182612015-05-29 09:32:35 -0500749 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500750
751 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500752 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500753 ASSERT_VK_SUCCESS(err);
754
755 // Introduce validation failure, destroy Image object before binding
756 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
757 ASSERT_VK_SUCCESS(err);
758
759 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500760 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500761 ASSERT_VK_SUCCESS(err);
762
763 msgType = m_errorMonitor->GetState(&msgString);
764 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while binding memory to a destroyed object";
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500765 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500766 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
767 }
768}
769
Tony Barbour8508b8e2015-04-09 10:48:04 -0600770TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600771{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600772 vk_testing::Fence testFence;
773 VK_DBG_MSG_TYPE msgType;
Tony Barbour30486ea2015-04-07 13:44:53 -0600774 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600775
776 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600777 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
778 fenceInfo.pNext = NULL;
779 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600780
Tony Barbour30486ea2015-04-07 13:44:53 -0600781 ASSERT_NO_FATAL_FAILURE(InitState());
782 ASSERT_NO_FATAL_FAILURE(InitViewport());
783 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
784
Tony Barbour01999182015-04-09 12:58:51 -0600785 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600786 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
787
Tony Barbour8508b8e2015-04-09 10:48:04 -0600788 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600789 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600790 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600791
792 testFence.init(*m_device, fenceInfo);
793 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600794 cmdBuffer.QueueCommandBuffer(testFence.obj());
Tony Barbour30486ea2015-04-07 13:44:53 -0600795 msgType = m_errorMonitor->GetState(&msgString);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600796 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
797 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500798 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600799 }
800
801}
802
803TEST_F(VkLayerTest, ResetUnsignaledFence)
804{
805 vk_testing::Fence testFence;
806 VK_DBG_MSG_TYPE msgType;
807 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600808 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600809 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
810 fenceInfo.pNext = NULL;
811
Tony Barbour8508b8e2015-04-09 10:48:04 -0600812 ASSERT_NO_FATAL_FAILURE(InitState());
813 testFence.init(*m_device, fenceInfo);
814 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600815 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600816 vkResetFences(m_device->device(), 1, fences);
817 msgType = m_errorMonitor->GetState(&msgString);
818 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 -0600819 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500820 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600821 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600822
823}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600824#endif
825#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600826TEST_F(VkLayerTest, WaitForUnsubmittedFence)
827{
828 vk_testing::Fence testFence;
829 VK_DBG_MSG_TYPE msgType;
830 std::string msgString;
831 VkFenceCreateInfo fenceInfo = {};
832 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
833 fenceInfo.pNext = NULL;
834
Tony Barbour54cdd192015-04-22 15:12:07 -0600835 ASSERT_NO_FATAL_FAILURE(InitState());
836 testFence.init(*m_device, fenceInfo);
837 m_errorMonitor->ClearState();
838 vkGetFenceStatus(m_device->device(),testFence.obj());
839 msgType = m_errorMonitor->GetState(&msgString);
840 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error asking for status of unsubmitted fence";
841 if (!strstr(msgString.c_str(),"Status Requested for Unsubmitted Fence")) {
842 FAIL() << "Error received was not Status Requested for Unsubmitted Fence";
843 }
844
845 VkFence fences[1] = {testFence.obj()};
846 m_errorMonitor->ClearState();
847 vkWaitForFences(m_device->device(), 1, fences, VK_TRUE, 0);
848 msgType = m_errorMonitor->GetState(&msgString);
849 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error for waiting for unsubmitted fence";
850 if (!strstr(msgString.c_str(),"Waiting for Unsubmitted Fence")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500851 FAIL() << "Error received was not 'Waiting for Unsubmitted Fence'";
Tony Barbour54cdd192015-04-22 15:12:07 -0600852 }
853}
854
Tony Barbourdb686622015-05-06 09:35:56 -0600855TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
856{
857 VkEventCreateInfo event_info;
858 VkEvent event;
859 VkMemoryRequirements mem_req;
860 size_t data_size = sizeof(mem_req);
861 VK_DBG_MSG_TYPE msgType;
862 std::string msgString;
863 VkResult err;
864
865 ASSERT_NO_FATAL_FAILURE(InitState());
866 memset(&event_info, 0, sizeof(event_info));
867 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
868
869 err = vkCreateEvent(device(), &event_info, &event);
870 ASSERT_VK_SUCCESS(err);
871 m_errorMonitor->ClearState();
872 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
873 &data_size, &mem_req);
874 msgType = m_errorMonitor->GetState(&msgString);
875 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from mismatched types in vkGetObjectInfo";
876 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500877 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600878 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500879}
Tony Barbourdb686622015-05-06 09:35:56 -0600880
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500881TEST_F(VkLayerTest, RasterStateNotBound)
882{
883 VK_DBG_MSG_TYPE msgType;
884 std::string msgString;
885
886 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
887
888 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
889
890 msgType = m_errorMonitor->GetState(&msgString);
891 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
892 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
893 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
894 }
895}
896
897TEST_F(VkLayerTest, ViewportStateNotBound)
898{
899 VK_DBG_MSG_TYPE msgType;
900 std::string msgString;
901 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
902
903 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
904
905 msgType = m_errorMonitor->GetState(&msgString);
906 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
907 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
908 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
909 }
910}
911
912TEST_F(VkLayerTest, ColorBlendStateNotBound)
913{
914 VK_DBG_MSG_TYPE msgType;
915 std::string msgString;
916
917 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
918
919 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
920
921 msgType = m_errorMonitor->GetState(&msgString);
922 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
923 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
924 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
925 }
926}
927
928TEST_F(VkLayerTest, DepthStencilStateNotBound)
929{
930 VK_DBG_MSG_TYPE msgType;
931 std::string msgString;
932
933 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
934
935 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
936
937 msgType = m_errorMonitor->GetState(&msgString);
938 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
939 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
940 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
941 }
Tony Barbourdb686622015-05-06 09:35:56 -0600942}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600943#endif
944#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600945TEST_F(VkLayerTest, PipelineNotBound)
946{
947 // Initiate Draw w/o a PSO bound
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600948 VK_DBG_MSG_TYPE msgType;
949 std::string msgString;
950
951 ASSERT_NO_FATAL_FAILURE(InitState());
952 m_errorMonitor->ClearState();
953 VkCommandBufferObj cmdBuffer(m_device);
954 BeginCommandBuffer(cmdBuffer);
955 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
956 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
957 msgType = m_errorMonitor->GetState(&msgString);
958 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
959 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
960 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
961 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600962}
963
964TEST_F(VkLayerTest, InvalidDescriptorPool)
965{
966 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
967 // The DS check for this is after driver has been called to validate DS internal data struct
968 // Attempt to clear DS Pool with bad object
969/* VK_DBG_MSG_TYPE msgType;
970 std::string msgString;
971 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
972 vkResetDescriptorPool(device(), badPool);
973
974 msgType = m_errorMonitor->GetState(&msgString);
975 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
976 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
977 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
978 }*/
979}
980
981TEST_F(VkLayerTest, InvalidDescriptorSet)
982{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600983 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
984 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600985 // Create a valid cmd buffer
986 // call vkCmdBindDescriptorSets w/ false DS
987}
988
989TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
990{
991 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
992 // The DS check for this is after driver has been called to validate DS internal data struct
993}
994
995TEST_F(VkLayerTest, InvalidPipeline)
996{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600997 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
998 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600999 // Create a valid cmd buffer
1000 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001001 VK_DBG_MSG_TYPE msgType;
1002 std::string msgString;
1003
1004 ASSERT_NO_FATAL_FAILURE(InitState());
1005 m_errorMonitor->ClearState();
1006 VkCommandBufferObj cmdBuffer(m_device);
1007 BeginCommandBuffer(cmdBuffer);
1008 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
1009 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
1010 msgType = m_errorMonitor->GetState(&msgString);
1011 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
1012 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
1013 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
1014 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001015}
1016
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001017TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001018{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001019 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
1020 VK_DBG_MSG_TYPE msgType;
1021 std::string msgString;
1022 VkResult err;
1023
1024 ASSERT_NO_FATAL_FAILURE(InitState());
1025 m_errorMonitor->ClearState();
1026 VkCommandBufferObj cmdBuffer(m_device);
1027 const VkDescriptorTypeCount ds_type_count = {
1028 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1029 .count = 1,
1030 };
1031 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1032 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1033 .pNext = NULL,
1034 .count = 1,
1035 .pTypeCount = &ds_type_count,
1036 };
1037 VkDescriptorPool ds_pool;
1038 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1039 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001040
1041 const VkDescriptorSetLayoutBinding dsl_binding = {
1042 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001043 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001044 .stageFlags = VK_SHADER_STAGE_ALL,
1045 .pImmutableSamplers = NULL,
1046 };
1047
1048 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1049 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1050 .pNext = NULL,
1051 .count = 1,
1052 .pBinding = &dsl_binding,
1053 };
1054 VkDescriptorSetLayout ds_layout;
1055 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1056 ASSERT_VK_SUCCESS(err);
1057
1058 VkDescriptorSet descriptorSet;
1059 uint32_t ds_count = 0;
1060 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1061 ASSERT_VK_SUCCESS(err);
1062
1063 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1064 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1065 .pNext = NULL,
1066 .descriptorSetCount = 1,
1067 .pSetLayouts = &ds_layout,
1068 };
1069
1070 VkPipelineLayout pipeline_layout;
1071 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1072 ASSERT_VK_SUCCESS(err);
1073
1074 size_t shader_len = strlen(bindStateVertShaderText);
1075 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1076 void* pCode = malloc(codeSize);
1077
1078 /* try version 0 first: VkShaderStage followed by GLSL */
1079 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1080 ((uint32_t *) pCode)[1] = 0;
1081 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1082 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1083
1084 const VkShaderCreateInfo vs_ci = {
1085 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1086 .pNext = NULL,
1087 .codeSize = codeSize,
1088 .pCode = pCode,
1089 .flags = 0,
1090 };
1091 VkShader vs;
1092 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1093 ASSERT_VK_SUCCESS(err);
1094
1095 const VkPipelineShader vs_pipe_shader = {
1096 .stage = VK_SHADER_STAGE_VERTEX,
1097 .shader = vs,
1098 .linkConstBufferCount = 0,
1099 .pLinkConstBufferInfo = NULL,
1100 .pSpecializationInfo = NULL,
1101 };
1102 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1103 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1104 .pNext = NULL,
1105 .shader = vs_pipe_shader,
1106 };
1107 const VkGraphicsPipelineCreateInfo gp_ci = {
1108 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1109 .pNext = &pipe_vs_ci,
1110 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1111 .layout = pipeline_layout,
1112 };
1113
1114 VkPipeline pipeline;
1115 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1116 ASSERT_VK_SUCCESS(err);
1117
1118 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1119 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1120
1121 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1122 m_device->get_device_queue();
1123 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1124
1125 msgType = m_errorMonitor->GetState(&msgString);
1126 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1127 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1128 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1129 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001130}
1131
1132TEST_F(VkLayerTest, InvalidDynamicStateObject)
1133{
1134 // Create a valid cmd buffer
1135 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001136 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1137 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001138}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001139
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001140TEST_F(VkLayerTest, VtxBufferBadIndex)
1141{
1142 // Bind VBO out-of-bounds for given PSO
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001143 VK_DBG_MSG_TYPE msgType;
1144 std::string msgString;
1145 VkResult err;
1146
1147 ASSERT_NO_FATAL_FAILURE(InitState());
1148 m_errorMonitor->ClearState();
1149 VkCommandBufferObj cmdBuffer(m_device);
1150 const VkDescriptorTypeCount ds_type_count = {
1151 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1152 .count = 1,
1153 };
1154 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1155 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1156 .pNext = NULL,
1157 .count = 1,
1158 .pTypeCount = &ds_type_count,
1159 };
1160 VkDescriptorPool ds_pool;
1161 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1162 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001163
1164 const VkDescriptorSetLayoutBinding dsl_binding = {
1165 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001166 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001167 .stageFlags = VK_SHADER_STAGE_ALL,
1168 .pImmutableSamplers = NULL,
1169 };
1170
1171 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1172 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1173 .pNext = NULL,
1174 .count = 1,
1175 .pBinding = &dsl_binding,
1176 };
1177 VkDescriptorSetLayout ds_layout;
1178 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1179 ASSERT_VK_SUCCESS(err);
1180
1181 VkDescriptorSet descriptorSet;
1182 uint32_t ds_count = 0;
1183 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1184 ASSERT_VK_SUCCESS(err);
1185
1186 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1187 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1188 .pNext = NULL,
1189 .descriptorSetCount = 1,
1190 .pSetLayouts = &ds_layout,
1191 };
1192
1193 VkPipelineLayout pipeline_layout;
1194 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1195 ASSERT_VK_SUCCESS(err);
1196
1197 size_t shader_len = strlen(bindStateVertShaderText);
1198 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1199 void* pCode = malloc(codeSize);
1200
1201 /* try version 0 first: VkShaderStage followed by GLSL */
1202 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1203 ((uint32_t *) pCode)[1] = 0;
1204 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1205 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1206
1207 const VkShaderCreateInfo vs_ci = {
1208 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1209 .pNext = NULL,
1210 .codeSize = codeSize,
1211 .pCode = pCode,
1212 .flags = 0,
1213 };
1214 VkShader vs;
1215 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1216
1217 const VkPipelineShader vs_pipe_shader = {
1218 .stage = VK_SHADER_STAGE_VERTEX,
1219 .shader = vs,
1220 .linkConstBufferCount = 0,
1221 .pLinkConstBufferInfo = NULL,
1222 .pSpecializationInfo = NULL,
1223 };
1224 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1225 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1226 .pNext = NULL,
1227 .shader = vs_pipe_shader,
1228 };
1229 const VkGraphicsPipelineCreateInfo gp_ci = {
1230 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1231 .pNext = &pipe_vs_ci,
1232 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1233 .layout = pipeline_layout,
1234 };
1235
1236 VkPipeline pipeline;
1237 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1238 ASSERT_VK_SUCCESS(err);
1239
1240 err= cmdBuffer.BeginCommandBuffer();
1241 ASSERT_VK_SUCCESS(err);
1242 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1243 // Should error before calling to driver so don't care about actual data
1244 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1245
1246 msgType = m_errorMonitor->GetState(&msgString);
1247 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
1248 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1249 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1250 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001251}
1252
1253TEST_F(VkLayerTest, DSTypeMismatch)
1254{
1255 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001256 VK_DBG_MSG_TYPE msgType;
1257 std::string msgString;
1258 VkResult err;
1259
1260 ASSERT_NO_FATAL_FAILURE(InitState());
1261 m_errorMonitor->ClearState();
1262 //VkDescriptorSetObj descriptorSet(m_device);
1263 const VkDescriptorTypeCount ds_type_count = {
1264 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1265 .count = 1,
1266 };
1267 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1268 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1269 .pNext = NULL,
1270 .count = 1,
1271 .pTypeCount = &ds_type_count,
1272 };
1273 VkDescriptorPool ds_pool;
1274 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1275 ASSERT_VK_SUCCESS(err);
1276 const VkDescriptorSetLayoutBinding dsl_binding = {
1277 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001278 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001279 .stageFlags = VK_SHADER_STAGE_ALL,
1280 .pImmutableSamplers = NULL,
1281 };
1282
1283 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1284 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1285 .pNext = NULL,
1286 .count = 1,
1287 .pBinding = &dsl_binding,
1288 };
1289 VkDescriptorSetLayout ds_layout;
1290 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1291 ASSERT_VK_SUCCESS(err);
1292
1293 VkDescriptorSet descriptorSet;
1294 uint32_t ds_count = 0;
1295 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1296 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001297
1298 const VkSamplerCreateInfo sampler_ci = {
1299 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1300 .pNext = NULL,
1301 .magFilter = VK_TEX_FILTER_NEAREST,
1302 .minFilter = VK_TEX_FILTER_NEAREST,
1303 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1304 .addressU = VK_TEX_ADDRESS_CLAMP,
1305 .addressV = VK_TEX_ADDRESS_CLAMP,
1306 .addressW = VK_TEX_ADDRESS_CLAMP,
1307 .mipLodBias = 1.0,
1308 .maxAnisotropy = 1,
1309 .compareOp = VK_COMPARE_OP_NEVER,
1310 .minLod = 1.0,
1311 .maxLod = 1.0,
1312 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1313 };
1314 VkSampler sampler;
1315 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1316 ASSERT_VK_SUCCESS(err);
1317
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001318 VkDescriptorInfo descriptor_info;
1319 memset(&descriptor_info, 0, sizeof(descriptor_info));
1320 descriptor_info.sampler = sampler;
1321
1322 VkWriteDescriptorSet descriptor_write;
1323 memset(&descriptor_write, 0, sizeof(descriptor_write));
1324 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1325 descriptor_write.destSet = descriptorSet;
1326 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001327 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001328 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1329 descriptor_write.pDescriptors = &descriptor_info;
1330
1331 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1332
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001333 msgType = m_errorMonitor->GetState(&msgString);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001334 std::cout << msgString << "\n";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001335 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 +08001336 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1337 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 -06001338 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001339}
1340
1341TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1342{
1343 // For overlapping Update, have arrayIndex exceed that of layout
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001344 VK_DBG_MSG_TYPE msgType;
1345 std::string msgString;
1346 VkResult err;
1347
1348 ASSERT_NO_FATAL_FAILURE(InitState());
1349 m_errorMonitor->ClearState();
1350 //VkDescriptorSetObj descriptorSet(m_device);
1351 const VkDescriptorTypeCount ds_type_count = {
1352 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1353 .count = 1,
1354 };
1355 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1356 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1357 .pNext = NULL,
1358 .count = 1,
1359 .pTypeCount = &ds_type_count,
1360 };
1361 VkDescriptorPool ds_pool;
1362 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1363 ASSERT_VK_SUCCESS(err);
1364 const VkDescriptorSetLayoutBinding dsl_binding = {
1365 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001366 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001367 .stageFlags = VK_SHADER_STAGE_ALL,
1368 .pImmutableSamplers = NULL,
1369 };
1370
1371 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1372 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1373 .pNext = NULL,
1374 .count = 1,
1375 .pBinding = &dsl_binding,
1376 };
1377 VkDescriptorSetLayout ds_layout;
1378 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1379 ASSERT_VK_SUCCESS(err);
1380
1381 VkDescriptorSet descriptorSet;
1382 uint32_t ds_count = 0;
1383 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1384 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001385
1386 const VkSamplerCreateInfo sampler_ci = {
1387 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1388 .pNext = NULL,
1389 .magFilter = VK_TEX_FILTER_NEAREST,
1390 .minFilter = VK_TEX_FILTER_NEAREST,
1391 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1392 .addressU = VK_TEX_ADDRESS_CLAMP,
1393 .addressV = VK_TEX_ADDRESS_CLAMP,
1394 .addressW = VK_TEX_ADDRESS_CLAMP,
1395 .mipLodBias = 1.0,
1396 .maxAnisotropy = 1,
1397 .compareOp = VK_COMPARE_OP_NEVER,
1398 .minLod = 1.0,
1399 .maxLod = 1.0,
1400 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1401 };
1402 VkSampler sampler;
1403 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1404 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001405
1406 VkDescriptorInfo descriptor_info;
1407 memset(&descriptor_info, 0, sizeof(descriptor_info));
1408 descriptor_info.sampler = sampler;
1409
1410 VkWriteDescriptorSet descriptor_write;
1411 memset(&descriptor_write, 0, sizeof(descriptor_write));
1412 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1413 descriptor_write.destSet = descriptorSet;
1414 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1415 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001416 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001417 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1418 descriptor_write.pDescriptors = &descriptor_info;
1419
1420 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1421
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001422 msgType = m_errorMonitor->GetState(&msgString);
1423 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 +08001424 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1425 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 -06001426 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001427}
1428
1429TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1430{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001431 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
1432 VK_DBG_MSG_TYPE msgType;
1433 std::string msgString;
1434 VkResult err;
1435
1436 ASSERT_NO_FATAL_FAILURE(InitState());
1437 m_errorMonitor->ClearState();
1438 //VkDescriptorSetObj descriptorSet(m_device);
1439 const VkDescriptorTypeCount ds_type_count = {
1440 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1441 .count = 1,
1442 };
1443 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1444 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1445 .pNext = NULL,
1446 .count = 1,
1447 .pTypeCount = &ds_type_count,
1448 };
1449 VkDescriptorPool ds_pool;
1450 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1451 ASSERT_VK_SUCCESS(err);
1452 const VkDescriptorSetLayoutBinding dsl_binding = {
1453 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001454 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001455 .stageFlags = VK_SHADER_STAGE_ALL,
1456 .pImmutableSamplers = NULL,
1457 };
1458
1459 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1460 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1461 .pNext = NULL,
1462 .count = 1,
1463 .pBinding = &dsl_binding,
1464 };
1465 VkDescriptorSetLayout ds_layout;
1466 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1467 ASSERT_VK_SUCCESS(err);
1468
1469 VkDescriptorSet descriptorSet;
1470 uint32_t ds_count = 0;
1471 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1472 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001473
1474 const VkSamplerCreateInfo sampler_ci = {
1475 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1476 .pNext = NULL,
1477 .magFilter = VK_TEX_FILTER_NEAREST,
1478 .minFilter = VK_TEX_FILTER_NEAREST,
1479 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1480 .addressU = VK_TEX_ADDRESS_CLAMP,
1481 .addressV = VK_TEX_ADDRESS_CLAMP,
1482 .addressW = VK_TEX_ADDRESS_CLAMP,
1483 .mipLodBias = 1.0,
1484 .maxAnisotropy = 1,
1485 .compareOp = VK_COMPARE_OP_NEVER,
1486 .minLod = 1.0,
1487 .maxLod = 1.0,
1488 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1489 };
1490 VkSampler sampler;
1491 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1492 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001493
1494 VkDescriptorInfo descriptor_info;
1495 memset(&descriptor_info, 0, sizeof(descriptor_info));
1496 descriptor_info.sampler = sampler;
1497
1498 VkWriteDescriptorSet descriptor_write;
1499 memset(&descriptor_write, 0, sizeof(descriptor_write));
1500 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1501 descriptor_write.destSet = descriptorSet;
1502 descriptor_write.destBinding = 2;
1503 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001504 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001505 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1506 descriptor_write.pDescriptors = &descriptor_info;
1507
1508 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1509
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001510 msgType = m_errorMonitor->GetState(&msgString);
1511 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ count too large for layout.";
1512 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1513 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1514 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001515}
1516
1517TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1518{
1519 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001520 VK_DBG_MSG_TYPE msgType;
1521 std::string msgString;
1522 VkResult err;
1523
1524 ASSERT_NO_FATAL_FAILURE(InitState());
1525 m_errorMonitor->ClearState();
1526 //VkDescriptorSetObj descriptorSet(m_device);
1527 const VkDescriptorTypeCount ds_type_count = {
1528 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1529 .count = 1,
1530 };
1531 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1532 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1533 .pNext = NULL,
1534 .count = 1,
1535 .pTypeCount = &ds_type_count,
1536 };
1537 VkDescriptorPool ds_pool;
1538 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1539 ASSERT_VK_SUCCESS(err);
1540 const VkDescriptorSetLayoutBinding dsl_binding = {
1541 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001542 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001543 .stageFlags = VK_SHADER_STAGE_ALL,
1544 .pImmutableSamplers = NULL,
1545 };
1546
1547 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1548 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1549 .pNext = NULL,
1550 .count = 1,
1551 .pBinding = &dsl_binding,
1552 };
1553 VkDescriptorSetLayout ds_layout;
1554 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1555 ASSERT_VK_SUCCESS(err);
1556
1557 VkDescriptorSet descriptorSet;
1558 uint32_t ds_count = 0;
1559 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1560 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001561
1562 const VkSamplerCreateInfo sampler_ci = {
1563 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1564 .pNext = NULL,
1565 .magFilter = VK_TEX_FILTER_NEAREST,
1566 .minFilter = VK_TEX_FILTER_NEAREST,
1567 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1568 .addressU = VK_TEX_ADDRESS_CLAMP,
1569 .addressV = VK_TEX_ADDRESS_CLAMP,
1570 .addressW = VK_TEX_ADDRESS_CLAMP,
1571 .mipLodBias = 1.0,
1572 .maxAnisotropy = 1,
1573 .compareOp = VK_COMPARE_OP_NEVER,
1574 .minLod = 1.0,
1575 .maxLod = 1.0,
1576 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1577 };
1578 VkSampler sampler;
1579 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1580 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001581
1582
1583 VkDescriptorInfo descriptor_info;
1584 memset(&descriptor_info, 0, sizeof(descriptor_info));
1585 descriptor_info.sampler = sampler;
1586
1587 VkWriteDescriptorSet descriptor_write;
1588 memset(&descriptor_write, 0, sizeof(descriptor_write));
1589 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1590 descriptor_write.destSet = descriptorSet;
1591 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001592 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001593 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1594 descriptor_write.pDescriptors = &descriptor_info;
1595
1596 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1597
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001598 msgType = m_errorMonitor->GetState(&msgString);
1599 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ invalid struct type.";
1600 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1601 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1602 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001603}
1604
1605TEST_F(VkLayerTest, NumSamplesMismatch)
1606{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001607 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1608 VK_DBG_MSG_TYPE msgType;
1609 std::string msgString;
1610 VkResult err;
1611
1612 ASSERT_NO_FATAL_FAILURE(InitState());
1613 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1614 m_errorMonitor->ClearState();
1615 VkCommandBufferObj cmdBuffer(m_device);
1616 const VkDescriptorTypeCount ds_type_count = {
1617 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1618 .count = 1,
1619 };
1620 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1621 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1622 .pNext = NULL,
1623 .count = 1,
1624 .pTypeCount = &ds_type_count,
1625 };
1626 VkDescriptorPool ds_pool;
1627 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1628 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001629
1630 const VkDescriptorSetLayoutBinding dsl_binding = {
1631 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001632 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001633 .stageFlags = VK_SHADER_STAGE_ALL,
1634 .pImmutableSamplers = NULL,
1635 };
1636
1637 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1638 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1639 .pNext = NULL,
1640 .count = 1,
1641 .pBinding = &dsl_binding,
1642 };
1643 VkDescriptorSetLayout ds_layout;
1644 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1645 ASSERT_VK_SUCCESS(err);
1646
1647 VkDescriptorSet descriptorSet;
1648 uint32_t ds_count = 0;
1649 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1650 ASSERT_VK_SUCCESS(err);
1651
1652 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1653 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1654 .pNext = NULL,
Tony Barbourd1e95582015-06-03 12:30:49 -06001655 .samples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001656 .multisampleEnable = 1,
1657 .sampleShadingEnable = 0,
1658 .minSampleShading = 1.0,
1659 .sampleMask = 15,
1660 };
1661
1662 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1663 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1664 .pNext = NULL,
1665 .descriptorSetCount = 1,
1666 .pSetLayouts = &ds_layout,
1667 };
1668
1669 VkPipelineLayout pipeline_layout;
1670 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1671 ASSERT_VK_SUCCESS(err);
1672
1673 size_t shader_len = strlen(bindStateVertShaderText);
1674 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1675 void* pCode = malloc(codeSize);
1676
1677 /* try version 0 first: VkShaderStage followed by GLSL */
1678 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1679 ((uint32_t *) pCode)[1] = 0;
1680 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1681 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1682
1683 const VkShaderCreateInfo vs_ci = {
1684 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1685 .pNext = NULL,
1686 .codeSize = codeSize,
1687 .pCode = pCode,
1688 .flags = 0,
1689 };
1690 VkShader vs;
1691 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1692 ASSERT_VK_SUCCESS(err);
1693
1694 const VkPipelineShader vs_pipe_shader = {
1695 .stage = VK_SHADER_STAGE_VERTEX,
1696 .shader = vs,
1697 .linkConstBufferCount = 0,
1698 .pLinkConstBufferInfo = NULL,
1699 .pSpecializationInfo = NULL,
1700 };
1701 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1702 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1703 .pNext = &pipe_ms_state_ci,
1704 .shader = vs_pipe_shader,
1705 };
1706 const VkGraphicsPipelineCreateInfo gp_ci = {
1707 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1708 .pNext = &pipe_vs_ci,
1709 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1710 .layout = pipeline_layout,
1711 };
1712
1713 VkPipeline pipeline;
1714 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1715 ASSERT_VK_SUCCESS(err);
1716
1717 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1718 BeginCommandBuffer(cmdBuffer);
1719 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1720
1721 msgType = m_errorMonitor->GetState(&msgString);
1722 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
1723 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1724 FAIL() << "Error received was not 'Num samples mismatch!...'";
1725 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001726}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001727#endif
1728#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001729#if GTEST_IS_THREADSAFE
1730struct thread_data_struct {
1731 VkCmdBuffer cmdBuffer;
1732 VkEvent event;
1733 bool bailout;
1734};
1735
1736extern "C" void *AddToCommandBuffer(void *arg)
1737{
1738 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1739 std::string msgString;
1740
1741 for (int i = 0; i<10000; i++) {
1742 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1743 if (data->bailout) {
1744 break;
1745 }
1746 }
1747 return NULL;
1748}
1749
1750TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1751{
1752 VK_DBG_MSG_TYPE msgType;
1753 std::string msgString;
1754 pthread_t thread;
1755 pthread_attr_t thread_attr;
1756
1757 ASSERT_NO_FATAL_FAILURE(InitState());
1758 ASSERT_NO_FATAL_FAILURE(InitViewport());
1759 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1760
1761 VkCommandBufferObj cmdBuffer(m_device);
1762
1763 m_errorMonitor->ClearState();
1764 pthread_attr_init(&thread_attr);
1765 BeginCommandBuffer(cmdBuffer);
1766
1767 VkEventCreateInfo event_info;
1768 VkEvent event;
1769 VkMemoryRequirements mem_req;
1770 size_t data_size = sizeof(mem_req);
1771 VkResult err;
1772
1773 memset(&event_info, 0, sizeof(event_info));
1774 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1775
1776 err = vkCreateEvent(device(), &event_info, &event);
1777 ASSERT_VK_SUCCESS(err);
1778
1779 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1780 &data_size, &mem_req);
1781 ASSERT_VK_SUCCESS(err);
1782
1783 VkMemoryAllocInfo mem_info;
1784 VkDeviceMemory event_mem;
1785
1786 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1787
1788 memset(&mem_info, 0, sizeof(mem_info));
1789 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1790 mem_info.allocationSize = mem_req.size;
1791 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1792 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1793 err = vkAllocMemory(device(), &mem_info, &event_mem);
1794 ASSERT_VK_SUCCESS(err);
1795
Mark Lobodzinski23182612015-05-29 09:32:35 -05001796 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001797 ASSERT_VK_SUCCESS(err);
1798
1799 err = vkResetEvent(device(), event);
1800 ASSERT_VK_SUCCESS(err);
1801
1802 struct thread_data_struct data;
1803 data.cmdBuffer = cmdBuffer.obj();
1804 data.event = event;
1805 data.bailout = false;
1806 m_errorMonitor->SetBailout(&data.bailout);
1807 // Add many entries to command buffer from another thread.
1808 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1809 // Add many entries to command buffer from this thread at the same time.
1810 AddToCommandBuffer(&data);
1811 pthread_join(thread, NULL);
1812 EndCommandBuffer(cmdBuffer);
1813
1814 msgType = m_errorMonitor->GetState(&msgString);
1815 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using one VkCommandBufferObj in two threads";
1816 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001817 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001818 }
1819
1820}
1821#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001822#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12001823
1824#if SHADER_CHECKER_TESTS
1825TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
1826{
1827 VK_DBG_MSG_TYPE msgType;
1828 std::string msgString;
1829 ASSERT_NO_FATAL_FAILURE(InitState());
1830 ScopedUseSpv spv(true);
1831
1832 char const *vsSource =
1833 "#version 140\n"
1834 "#extension GL_ARB_separate_shader_objects: require\n"
1835 "#extension GL_ARB_shading_language_420pack: require\n"
1836 "\n"
1837 "layout(location=0) out float x;\n"
1838 "void main(){\n"
1839 " gl_Position = vec4(1);\n"
1840 " x = 0;\n"
1841 "}\n";
1842 char const *fsSource =
1843 "#version 140\n"
1844 "#extension GL_ARB_separate_shader_objects: require\n"
1845 "#extension GL_ARB_shading_language_420pack: require\n"
1846 "\n"
1847 "layout(location=0) out vec4 color;\n"
1848 "void main(){\n"
1849 " color = vec4(1);\n"
1850 "}\n";
1851
1852 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1853 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1854
1855 VkPipelineObj pipe(m_device);
1856 pipe.AddShader(&vs);
1857 pipe.AddShader(&fs);
1858
1859 VkCommandBufferObj dummyCmd(m_device);
1860 VkDescriptorSetObj descriptorSet(m_device);
1861 descriptorSet.AppendDummy();
1862 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1863
1864 m_errorMonitor->ClearState();
1865 pipe.CreateVKPipeline(descriptorSet);
1866
1867 msgType = m_errorMonitor->GetState(&msgString);
1868
1869 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
1870 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
1871 FAIL() << "Incorrect warning: " << msgString;
1872 }
1873}
Chris Forbes5af3bf22015-05-25 11:13:08 +12001874
Chris Forbes3c10b852015-05-25 11:13:13 +12001875TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
1876{
1877 VK_DBG_MSG_TYPE msgType;
1878 std::string msgString;
1879 ASSERT_NO_FATAL_FAILURE(InitState());
1880 ScopedUseSpv spv(true);
1881
1882 char const *vsSource =
1883 "#version 140\n"
1884 "#extension GL_ARB_separate_shader_objects: require\n"
1885 "#extension GL_ARB_shading_language_420pack: require\n"
1886 "\n"
1887 "void main(){\n"
1888 " gl_Position = vec4(1);\n"
1889 "}\n";
1890 char const *fsSource =
1891 "#version 140\n"
1892 "#extension GL_ARB_separate_shader_objects: require\n"
1893 "#extension GL_ARB_shading_language_420pack: require\n"
1894 "\n"
1895 "layout(location=0) in float x;\n"
1896 "layout(location=0) out vec4 color;\n"
1897 "void main(){\n"
1898 " color = vec4(x);\n"
1899 "}\n";
1900
1901 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1902 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1903
1904 VkPipelineObj pipe(m_device);
1905 pipe.AddShader(&vs);
1906 pipe.AddShader(&fs);
1907
1908 VkCommandBufferObj dummyCmd(m_device);
1909 VkDescriptorSetObj descriptorSet(m_device);
1910 descriptorSet.AppendDummy();
1911 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1912
1913 m_errorMonitor->ClearState();
1914 pipe.CreateVKPipeline(descriptorSet);
1915
1916 msgType = m_errorMonitor->GetState(&msgString);
1917
1918 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
1919 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
1920 FAIL() << "Incorrect error: " << msgString;
1921 }
1922}
1923
Chris Forbescc281692015-05-25 11:13:17 +12001924TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
1925{
1926 VK_DBG_MSG_TYPE msgType;
1927 std::string msgString;
1928 ASSERT_NO_FATAL_FAILURE(InitState());
1929 ScopedUseSpv spv(true);
1930
1931 char const *vsSource =
1932 "#version 140\n"
1933 "#extension GL_ARB_separate_shader_objects: require\n"
1934 "#extension GL_ARB_shading_language_420pack: require\n"
1935 "\n"
1936 "layout(location=0) out int x;\n"
1937 "void main(){\n"
1938 " x = 0;\n"
1939 " gl_Position = vec4(1);\n"
1940 "}\n";
1941 char const *fsSource =
1942 "#version 140\n"
1943 "#extension GL_ARB_separate_shader_objects: require\n"
1944 "#extension GL_ARB_shading_language_420pack: require\n"
1945 "\n"
1946 "layout(location=0) in float x;\n" /* VS writes int */
1947 "layout(location=0) out vec4 color;\n"
1948 "void main(){\n"
1949 " color = vec4(x);\n"
1950 "}\n";
1951
1952 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1953 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1954
1955 VkPipelineObj pipe(m_device);
1956 pipe.AddShader(&vs);
1957 pipe.AddShader(&fs);
1958
1959 VkCommandBufferObj dummyCmd(m_device);
1960 VkDescriptorSetObj descriptorSet(m_device);
1961 descriptorSet.AppendDummy();
1962 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1963
1964 m_errorMonitor->ClearState();
1965 pipe.CreateVKPipeline(descriptorSet);
1966
1967 msgType = m_errorMonitor->GetState(&msgString);
1968
1969 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
1970 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
1971 FAIL() << "Incorrect error: " << msgString;
1972 }
1973}
1974
Chris Forbes8291c052015-05-25 11:13:28 +12001975TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
1976{
1977 VK_DBG_MSG_TYPE msgType;
1978 std::string msgString;
1979 ASSERT_NO_FATAL_FAILURE(InitState());
1980 ScopedUseSpv spv(true);
1981
1982 VkVertexInputBindingDescription input_binding;
1983 memset(&input_binding, 0, sizeof(input_binding));
1984
1985 VkVertexInputAttributeDescription input_attrib;
1986 memset(&input_attrib, 0, sizeof(input_attrib));
1987 input_attrib.format = VK_FORMAT_R32_SFLOAT;
1988
1989 char const *vsSource =
1990 "#version 140\n"
1991 "#extension GL_ARB_separate_shader_objects: require\n"
1992 "#extension GL_ARB_shading_language_420pack: require\n"
1993 "\n"
1994 "void main(){\n"
1995 " gl_Position = vec4(1);\n"
1996 "}\n";
1997 char const *fsSource =
1998 "#version 140\n"
1999 "#extension GL_ARB_separate_shader_objects: require\n"
2000 "#extension GL_ARB_shading_language_420pack: require\n"
2001 "\n"
2002 "layout(location=0) out vec4 color;\n"
2003 "void main(){\n"
2004 " color = vec4(1);\n"
2005 "}\n";
2006
2007 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2008 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2009
2010 VkPipelineObj pipe(m_device);
2011 pipe.AddShader(&vs);
2012 pipe.AddShader(&fs);
2013
2014 pipe.AddVertexInputBindings(&input_binding, 1);
2015 pipe.AddVertexInputAttribs(&input_attrib, 1);
2016
2017 VkCommandBufferObj dummyCmd(m_device);
2018 VkDescriptorSetObj descriptorSet(m_device);
2019 descriptorSet.AppendDummy();
2020 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2021
2022 m_errorMonitor->ClearState();
2023 pipe.CreateVKPipeline(descriptorSet);
2024
2025 msgType = m_errorMonitor->GetState(&msgString);
2026
2027 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
2028 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
2029 FAIL() << "Incorrect warning: " << msgString;
2030 }
2031}
2032
Chris Forbes37367e62015-05-25 11:13:29 +12002033TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
2034{
2035 VK_DBG_MSG_TYPE msgType;
2036 std::string msgString;
2037 ASSERT_NO_FATAL_FAILURE(InitState());
2038 ScopedUseSpv spv(true);
2039
2040 char const *vsSource =
2041 "#version 140\n"
2042 "#extension GL_ARB_separate_shader_objects: require\n"
2043 "#extension GL_ARB_shading_language_420pack: require\n"
2044 "\n"
2045 "layout(location=0) in vec4 x;\n" /* not provided */
2046 "void main(){\n"
2047 " gl_Position = x;\n"
2048 "}\n";
2049 char const *fsSource =
2050 "#version 140\n"
2051 "#extension GL_ARB_separate_shader_objects: require\n"
2052 "#extension GL_ARB_shading_language_420pack: require\n"
2053 "\n"
2054 "layout(location=0) out vec4 color;\n"
2055 "void main(){\n"
2056 " color = vec4(1);\n"
2057 "}\n";
2058
2059 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2060 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2061
2062 VkPipelineObj pipe(m_device);
2063 pipe.AddShader(&vs);
2064 pipe.AddShader(&fs);
2065
2066 VkCommandBufferObj dummyCmd(m_device);
2067 VkDescriptorSetObj descriptorSet(m_device);
2068 descriptorSet.AppendDummy();
2069 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2070
2071 m_errorMonitor->ClearState();
2072 pipe.CreateVKPipeline(descriptorSet);
2073
2074 msgType = m_errorMonitor->GetState(&msgString);
2075
2076 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2077 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2078 FAIL() << "Incorrect warning: " << msgString;
2079 }
2080}
2081
Chris Forbesa4b02322015-05-25 11:13:31 +12002082TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2083{
2084 VK_DBG_MSG_TYPE msgType;
2085 std::string msgString;
2086 ASSERT_NO_FATAL_FAILURE(InitState());
2087 ScopedUseSpv spv(true);
2088
2089 VkVertexInputBindingDescription input_binding;
2090 memset(&input_binding, 0, sizeof(input_binding));
2091
2092 VkVertexInputAttributeDescription input_attrib;
2093 memset(&input_attrib, 0, sizeof(input_attrib));
2094 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2095
2096 char const *vsSource =
2097 "#version 140\n"
2098 "#extension GL_ARB_separate_shader_objects: require\n"
2099 "#extension GL_ARB_shading_language_420pack: require\n"
2100 "\n"
2101 "layout(location=0) in int x;\n" /* attrib provided float */
2102 "void main(){\n"
2103 " gl_Position = vec4(x);\n"
2104 "}\n";
2105 char const *fsSource =
2106 "#version 140\n"
2107 "#extension GL_ARB_separate_shader_objects: require\n"
2108 "#extension GL_ARB_shading_language_420pack: require\n"
2109 "\n"
2110 "layout(location=0) out vec4 color;\n"
2111 "void main(){\n"
2112 " color = vec4(1);\n"
2113 "}\n";
2114
2115 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2116 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2117
2118 VkPipelineObj pipe(m_device);
2119 pipe.AddShader(&vs);
2120 pipe.AddShader(&fs);
2121
2122 pipe.AddVertexInputBindings(&input_binding, 1);
2123 pipe.AddVertexInputAttribs(&input_attrib, 1);
2124
2125 VkCommandBufferObj dummyCmd(m_device);
2126 VkDescriptorSetObj descriptorSet(m_device);
2127 descriptorSet.AppendDummy();
2128 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2129
2130 m_errorMonitor->ClearState();
2131 pipe.CreateVKPipeline(descriptorSet);
2132
2133 msgType = m_errorMonitor->GetState(&msgString);
2134
2135 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2136 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2137 FAIL() << "Incorrect error: " << msgString;
2138 }
2139}
2140
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002141TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2142{
2143 VK_DBG_MSG_TYPE msgType;
2144 std::string msgString;
2145 ASSERT_NO_FATAL_FAILURE(InitState());
2146 ScopedUseSpv spv(true);
2147
2148 /* Two binding descriptions for binding 0 */
2149 VkVertexInputBindingDescription input_bindings[2];
2150 memset(input_bindings, 0, sizeof(input_bindings));
2151
2152 VkVertexInputAttributeDescription input_attrib;
2153 memset(&input_attrib, 0, sizeof(input_attrib));
2154 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2155
2156 char const *vsSource =
2157 "#version 140\n"
2158 "#extension GL_ARB_separate_shader_objects: require\n"
2159 "#extension GL_ARB_shading_language_420pack: require\n"
2160 "\n"
2161 "layout(location=0) in float x;\n" /* attrib provided float */
2162 "void main(){\n"
2163 " gl_Position = vec4(x);\n"
2164 "}\n";
2165 char const *fsSource =
2166 "#version 140\n"
2167 "#extension GL_ARB_separate_shader_objects: require\n"
2168 "#extension GL_ARB_shading_language_420pack: require\n"
2169 "\n"
2170 "layout(location=0) out vec4 color;\n"
2171 "void main(){\n"
2172 " color = vec4(1);\n"
2173 "}\n";
2174
2175 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2176 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2177
2178 VkPipelineObj pipe(m_device);
2179 pipe.AddShader(&vs);
2180 pipe.AddShader(&fs);
2181
2182 pipe.AddVertexInputBindings(input_bindings, 2);
2183 pipe.AddVertexInputAttribs(&input_attrib, 1);
2184
2185 VkCommandBufferObj dummyCmd(m_device);
2186 VkDescriptorSetObj descriptorSet(m_device);
2187 descriptorSet.AppendDummy();
2188 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2189
2190 m_errorMonitor->ClearState();
2191 pipe.CreateVKPipeline(descriptorSet);
2192
2193 msgType = m_errorMonitor->GetState(&msgString);
2194
2195 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2196 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2197 FAIL() << "Incorrect error: " << msgString;
2198 }
2199}
Chris Forbes4c948702015-05-25 11:13:32 +12002200TEST_F(VkLayerTest, CreatePipelineFragmentBroadcastWithInteger)
2201{
2202 VK_DBG_MSG_TYPE msgType;
2203 std::string msgString;
2204 ASSERT_NO_FATAL_FAILURE(InitState());
2205 ScopedUseSpv spv(true);
2206
2207 char const *vsSource =
2208 "#version 140\n"
2209 "#extension GL_ARB_separate_shader_objects: require\n"
2210 "#extension GL_ARB_shading_language_420pack: require\n"
2211 "\n"
2212 "void main(){\n"
2213 " gl_Position = vec4(1);\n"
2214 "}\n";
2215 char const *fsSource =
2216 "#version 140\n"
2217 "#extension GL_ARB_separate_shader_objects: require\n"
2218 "#extension GL_ARB_shading_language_420pack: require\n"
2219 "\n"
2220 "void main(){\n"
2221 " gl_FragColor = vec4(1);\n" /* broadcast */
2222 "}\n";
2223
2224 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2225 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2226
2227 VkPipelineObj pipe(m_device);
2228 pipe.AddShader(&vs);
2229 pipe.AddShader(&fs);
2230
2231 VkPipelineCbAttachmentState attach;
2232 memset(&attach, 0, sizeof(attach));
2233 attach.format = VK_FORMAT_R8_UINT; /* not unorm/snorm/float */
2234
2235 pipe.AddColorAttachment(1, &attach);
2236
2237 VkCommandBufferObj dummyCmd(m_device);
2238 VkDescriptorSetObj descriptorSet(m_device);
2239 descriptorSet.AppendDummy();
2240 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2241
2242 m_errorMonitor->ClearState();
2243 pipe.CreateVKPipeline(descriptorSet);
2244
2245 msgType = m_errorMonitor->GetState(&msgString);
2246
2247 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2248 if (!strstr(msgString.c_str(),"CB format should not be SINT or UINT when using broadcast")) {
2249 FAIL() << "Incorrect error: " << msgString;
2250 }
2251}
2252
Chris Forbesc12ef122015-05-25 11:13:40 +12002253/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2254 * rejects it. */
2255
2256TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2257{
2258 VK_DBG_MSG_TYPE msgType;
2259 std::string msgString;
2260 ASSERT_NO_FATAL_FAILURE(InitState());
2261 ScopedUseSpv spv(true);
2262
2263 char const *vsSource =
2264 "#version 140\n"
2265 "#extension GL_ARB_separate_shader_objects: require\n"
2266 "#extension GL_ARB_shading_language_420pack: require\n"
2267 "\n"
2268 "void main(){\n"
2269 " gl_Position = vec4(1);\n"
2270 "}\n";
2271 char const *fsSource =
2272 "#version 140\n"
2273 "#extension GL_ARB_separate_shader_objects: require\n"
2274 "#extension GL_ARB_shading_language_420pack: require\n"
2275 "\n"
2276 "void main(){\n"
2277 "}\n";
2278
2279 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2280 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2281
2282 VkPipelineObj pipe(m_device);
2283 pipe.AddShader(&vs);
2284 pipe.AddShader(&fs);
2285
2286 /* implicit CB 0 set up by the test framework, not written */
2287
2288 VkCommandBufferObj dummyCmd(m_device);
2289 VkDescriptorSetObj descriptorSet(m_device);
2290 descriptorSet.AppendDummy();
2291 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2292
2293 m_errorMonitor->ClearState();
2294 pipe.CreateVKPipeline(descriptorSet);
2295
2296 msgType = m_errorMonitor->GetState(&msgString);
2297
2298 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2299 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2300 FAIL() << "Incorrect error: " << msgString;
2301 }
2302}
2303
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002304TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2305{
2306 VK_DBG_MSG_TYPE msgType;
2307 std::string msgString;
2308 ASSERT_NO_FATAL_FAILURE(InitState());
2309 ScopedUseSpv spv(true);
2310
2311 char const *vsSource =
2312 "#version 140\n"
2313 "#extension GL_ARB_separate_shader_objects: require\n"
2314 "#extension GL_ARB_shading_language_420pack: require\n"
2315 "\n"
2316 "void main(){\n"
2317 " gl_Position = vec4(1);\n"
2318 "}\n";
2319 char const *fsSource =
2320 "#version 140\n"
2321 "#extension GL_ARB_separate_shader_objects: require\n"
2322 "#extension GL_ARB_shading_language_420pack: require\n"
2323 "\n"
2324 "layout(location=0) out vec4 x;\n"
2325 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2326 "void main(){\n"
2327 " x = vec4(1);\n"
2328 " y = vec4(1);\n"
2329 "}\n";
2330
2331 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2332 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2333
2334 VkPipelineObj pipe(m_device);
2335 pipe.AddShader(&vs);
2336 pipe.AddShader(&fs);
2337
2338 /* implicit CB 0 set up by the test framework */
2339 /* FS writes CB 1, but we don't configure it */
2340
2341 VkCommandBufferObj dummyCmd(m_device);
2342 VkDescriptorSetObj descriptorSet(m_device);
2343 descriptorSet.AppendDummy();
2344 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2345
2346 m_errorMonitor->ClearState();
2347 pipe.CreateVKPipeline(descriptorSet);
2348
2349 msgType = m_errorMonitor->GetState(&msgString);
2350
2351 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
2352 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2353 FAIL() << "Incorrect warning: " << msgString;
2354 }
2355}
2356
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002357TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2358{
2359 VK_DBG_MSG_TYPE msgType;
2360 std::string msgString;
2361 ASSERT_NO_FATAL_FAILURE(InitState());
2362 ScopedUseSpv spv(true);
2363
2364 char const *vsSource =
2365 "#version 140\n"
2366 "#extension GL_ARB_separate_shader_objects: require\n"
2367 "#extension GL_ARB_shading_language_420pack: require\n"
2368 "\n"
2369 "void main(){\n"
2370 " gl_Position = vec4(1);\n"
2371 "}\n";
2372 char const *fsSource =
2373 "#version 140\n"
2374 "#extension GL_ARB_separate_shader_objects: require\n"
2375 "#extension GL_ARB_shading_language_420pack: require\n"
2376 "\n"
2377 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2378 "void main(){\n"
2379 " x = ivec4(1);\n"
2380 "}\n";
2381
2382 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2383 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2384
2385 VkPipelineObj pipe(m_device);
2386 pipe.AddShader(&vs);
2387 pipe.AddShader(&fs);
2388
2389 /* implicit CB 0 set up by test framework, is UNORM. */
2390
2391 VkCommandBufferObj dummyCmd(m_device);
2392 VkDescriptorSetObj descriptorSet(m_device);
2393 descriptorSet.AppendDummy();
2394 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2395
2396 m_errorMonitor->ClearState();
2397 pipe.CreateVKPipeline(descriptorSet);
2398
2399 msgType = m_errorMonitor->GetState(&msgString);
2400
2401 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2402 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2403 FAIL() << "Incorrect error: " << msgString;
2404 }
2405}
Chris Forbesc2050732015-06-05 14:43:36 +12002406
2407TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2408{
2409 VK_DBG_MSG_TYPE msgType;
2410 std::string msgString;
2411 ASSERT_NO_FATAL_FAILURE(InitState());
2412 /* Intentionally provided GLSL rather than compiling to SPIRV first */
2413 ScopedUseSpv spv(false);
2414
2415 char const *vsSource =
2416 "#version 140\n"
2417 "#extension GL_ARB_separate_shader_objects: require\n"
2418 "#extension GL_ARB_shading_language_420pack: require\n"
2419 "\n"
2420 "void main(){\n"
2421 " gl_Position = vec4(1);\n"
2422 "}\n";
2423 char const *fsSource =
2424 "#version 140\n"
2425 "#extension GL_ARB_separate_shader_objects: require\n"
2426 "#extension GL_ARB_shading_language_420pack: require\n"
2427 "\n"
2428 "layout(location=0) out vec4 x;\n"
2429 "void main(){\n"
2430 " x = vec4(1);\n"
2431 "}\n";
2432
2433 m_errorMonitor->ClearState();
2434
2435 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2436 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2437
2438
2439 VkPipelineObj pipe(m_device);
2440 pipe.AddShader(&vs);
2441 pipe.AddShader(&fs);
2442
2443 /* implicit CB 0 set up by test framework, is UNORM. */
2444
2445 VkCommandBufferObj dummyCmd(m_device);
2446 VkDescriptorSetObj descriptorSet(m_device);
2447 descriptorSet.AppendDummy();
2448 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2449
2450 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2451 /* pipeline creation should have succeeded */
2452 ASSERT_EQ(VK_SUCCESS, res);
2453
2454 /* should have emitted a warning: the shader is not SPIRV, so we're
2455 * not going to be able to analyze it */
2456 msgType = m_errorMonitor->GetState(&msgString);
2457 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
2458 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2459 FAIL() << "Incorrect warning: " << msgString;
2460 }
2461}
Chris Forbes01c9db72015-06-04 09:25:25 +12002462#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002463
Tony Barbour30486ea2015-04-07 13:44:53 -06002464int main(int argc, char **argv) {
2465 int result;
2466
2467 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002468 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002469
2470 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2471
2472 result = RUN_ALL_TESTS();
2473
Tony Barbour01999182015-04-09 12:58:51 -06002474 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002475 return result;
2476}