blob: f65b30717b9ab1c357313e9045f9b5677ff31e96 [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[] =
Cody Northrop74a2d2c2015-06-16 17:32:04 -060054 "#version 140\n"
55 "#extension GL_ARB_separate_shader_objects: require\n"
56 "#extension GL_ARB_shading_language_420pack: require\n"
57 "\n"
58 "layout(location = 0) out vec4 uFragColor;\n"
59 "void main(){\n"
60 " uFragColor = vec4(0,1,0,1);\n"
61 "}\n";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050062
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060063void VKAPI myDbgFunc(
64 VK_DBG_MSG_TYPE msgType,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060065 VkValidationLevel validationLevel,
Mike Stroyan230e6252015-04-17 12:36:38 -060066 VkObject srcObject,
Tony Barbour30486ea2015-04-07 13:44:53 -060067 size_t location,
68 int32_t msgCode,
69 const char* pMsg,
70 void* pUserData);
71
72class ErrorMonitor {
73public:
Tony Barbour0c1bdc62015-04-29 17:34:29 -060074 ErrorMonitor()
Tony Barbour30486ea2015-04-07 13:44:53 -060075 {
Mike Stroyan09aae812015-05-12 16:00:45 -060076 pthread_mutexattr_t attr;
77 pthread_mutexattr_init(&attr);
78 pthread_mutex_init(&m_mutex, &attr);
79 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060080 m_msgType = VK_DBG_MSG_UNKNOWN;
Mike Stroyan09aae812015-05-12 16:00:45 -060081 m_bailout = NULL;
82 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060083 }
84 void ClearState()
85 {
Mike Stroyan09aae812015-05-12 16:00:45 -060086 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060087 m_msgType = VK_DBG_MSG_UNKNOWN;
Tony Barbour30486ea2015-04-07 13:44:53 -060088 m_msgString.clear();
Mike Stroyan09aae812015-05-12 16:00:45 -060089 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060090 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060091 VK_DBG_MSG_TYPE GetState(std::string *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060092 {
Mike Stroyan09aae812015-05-12 16:00:45 -060093 pthread_mutex_lock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060094 *msgString = m_msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -060095 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060096 return m_msgType;
97 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060098 void SetState(VK_DBG_MSG_TYPE msgType, const char *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060099 {
Mike Stroyan09aae812015-05-12 16:00:45 -0600100 pthread_mutex_lock(&m_mutex);
101 if (m_bailout != NULL) {
102 *m_bailout = true;
103 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600104 m_msgType = msgType;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600105 m_msgString.reserve(strlen(msgString));
106 m_msgString = msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -0600107 pthread_mutex_unlock(&m_mutex);
108 }
109 void SetBailout(bool *bailout)
110 {
111 m_bailout = bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600112 }
113
114private:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600115 VK_DBG_MSG_TYPE m_msgType;
Mike Stroyan09aae812015-05-12 16:00:45 -0600116 std::string m_msgString;
117 pthread_mutex_t m_mutex;
118 bool* m_bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600119};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500120
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600121void VKAPI myDbgFunc(
Mike Stroyan230e6252015-04-17 12:36:38 -0600122 VK_DBG_MSG_TYPE msgType,
123 VkValidationLevel validationLevel,
124 VkObject srcObject,
Tony Barbour30486ea2015-04-07 13:44:53 -0600125 size_t location,
126 int32_t msgCode,
127 const char* pMsg,
128 void* pUserData)
129{
Tony Barbour8508b8e2015-04-09 10:48:04 -0600130 if (msgType == VK_DBG_MSG_WARNING || msgType == VK_DBG_MSG_ERROR) {
131 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
132 errMonitor->SetState(msgType, pMsg);
133 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600134}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500135
Tony Barbour01999182015-04-09 12:58:51 -0600136class VkLayerTest : public VkRenderFramework
Tony Barbour30486ea2015-04-07 13:44:53 -0600137{
138public:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600139 VkResult BeginCommandBuffer(VkCommandBufferObj &cmdBuffer);
140 VkResult EndCommandBuffer(VkCommandBufferObj &cmdBuffer);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500141 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
142 void GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask);
Tony Barbour30486ea2015-04-07 13:44:53 -0600143
144protected:
Tony Barbour01999182015-04-09 12:58:51 -0600145 VkMemoryRefManager m_memoryRefManager;
146 ErrorMonitor *m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600147
148 virtual void SetUp() {
Chris Forbesd0f3f442015-05-25 11:13:00 +1200149 const char *extension_names[] = {"MemTracker", "ObjectTracker", "Threading", "DrawState", "ShaderChecker"};
Mike Stroyan09aae812015-05-12 16:00:45 -0600150 const std::vector<const char *> extensions(extension_names,
151 extension_names + sizeof(extension_names)/sizeof(extension_names[0]));
Tony Barbour950ebc02015-04-23 12:55:36 -0600152
153 size_t extSize = sizeof(uint32_t);
154 uint32_t extCount = 0;
Tony Barbour04ada4a2015-04-23 15:28:27 -0600155 VkResult U_ASSERT_ONLY err;
Tony Barbour950ebc02015-04-23 12:55:36 -0600156 err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount);
157 assert(!err);
158
159 VkExtensionProperties extProp;
160 extSize = sizeof(VkExtensionProperties);
161 bool32_t extFound;
162
Tony Barbour04ada4a2015-04-23 15:28:27 -0600163 for (uint32_t i = 0; i < extensions.size(); i++) {
Tony Barbour950ebc02015-04-23 12:55:36 -0600164 extFound = 0;
165 for (uint32_t j = 0; j < extCount; j++) {
166 err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_PROPERTIES, j, &extSize, &extProp);
Tony Barbour04ada4a2015-04-23 15:28:27 -0600167 assert(!err);
168 if (!strcmp(extensions[i], extProp.extName)) {
Tony Barbour950ebc02015-04-23 12:55:36 -0600169 extFound = 1;
170 break;
171 }
172 }
Tony Barbour04ada4a2015-04-23 15:28:27 -0600173 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 -0600174 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600175
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500176 // Force layer output level to be >= WARNING so that we catch those messages but ignore others
177 setLayerOptionEnum("MemTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
178 setLayerOptionEnum("ObjectTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
179 setLayerOptionEnum("ThreadingReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600180 setLayerOptionEnum("DrawStateReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Chris Forbesd0f3f442015-05-25 11:13:00 +1200181 setLayerOptionEnum("ShaderCheckerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500182
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600183 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600184 this->app_info.pNext = NULL;
185 this->app_info.pAppName = "layer_tests";
186 this->app_info.appVersion = 1;
187 this->app_info.pEngineName = "unittest";
188 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600189 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600190
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600191 m_errorMonitor = new ErrorMonitor;
192 InitFramework(extensions, myDbgFunc, m_errorMonitor);
193
Tony Barbour30486ea2015-04-07 13:44:53 -0600194 }
195
196 virtual void TearDown() {
197 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600198 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600199 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600200 }
201};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500202
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600203VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600204{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600205 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600206
207 result = cmdBuffer.BeginCommandBuffer();
208
209 /*
210 * For render test all drawing happens in a single render pass
211 * on a single command buffer.
212 */
Chris Forbesfe133ef2015-06-16 14:05:59 +1200213 if (VK_SUCCESS == result && renderPass()) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600214 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
215 }
216
217 return result;
218}
219
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600220VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600221{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600222 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600223
Chris Forbesfe133ef2015-06-16 14:05:59 +1200224 if (renderPass()) {
225 cmdBuffer.EndRenderPass(renderPass());
226 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600227
228 result = cmdBuffer.EndCommandBuffer();
229
230 return result;
231}
232
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500233void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
234{
235 // Create identity matrix
236 int i;
237 struct vktriangle_vs_uniform data;
238
239 glm::mat4 Projection = glm::mat4(1.0f);
240 glm::mat4 View = glm::mat4(1.0f);
241 glm::mat4 Model = glm::mat4(1.0f);
242 glm::mat4 MVP = Projection * View * Model;
243 const int matrixSize = sizeof(MVP);
244 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
245
246 memcpy(&data.mvp, &MVP[0][0], matrixSize);
247
248 static const Vertex tri_data[] =
249 {
250 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
251 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
252 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
253 };
254
255 for (i=0; i<3; i++) {
256 data.position[i][0] = tri_data[i].posX;
257 data.position[i][1] = tri_data[i].posY;
258 data.position[i][2] = tri_data[i].posZ;
259 data.position[i][3] = tri_data[i].posW;
260 data.color[i][0] = tri_data[i].r;
261 data.color[i][1] = tri_data[i].g;
262 data.color[i][2] = tri_data[i].b;
263 data.color[i][3] = tri_data[i].a;
264 }
265
266 ASSERT_NO_FATAL_FAILURE(InitState());
267 ASSERT_NO_FATAL_FAILURE(InitViewport());
268
269 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
270
271 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
272 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
273
274 VkPipelineObj pipelineobj(m_device);
275 pipelineobj.AddShader(&vs);
276 pipelineobj.AddShader(&ps);
277
278 VkDescriptorSetObj descriptorSet(m_device);
279 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
280
281 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
282 VkCommandBufferObj cmdBuffer(m_device);
283 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
284
285 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
286
287 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
288
289 // render triangle
290 cmdBuffer.Draw(0, 3, 0, 1);
291
292 // finalize recording of the command buffer
293 EndCommandBuffer(cmdBuffer);
294
295 cmdBuffer.QueueCommandBuffer();
296}
297
298void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
299{
300 if (m_depthStencil->Initialized()) {
301 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
302 } else {
303 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
304 }
305
306 cmdBuffer->PrepareAttachments();
307 if ((failMask & BsoFailRaster) != BsoFailRaster) {
308 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
309 }
310 if ((failMask & BsoFailViewport) != BsoFailViewport) {
311 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
312 }
313 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
314 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
315 }
316 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
317 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
318 }
319 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
320 pipelineobj.CreateVKPipeline(descriptorSet);
321 cmdBuffer->BindPipeline(pipelineobj);
322 cmdBuffer->BindDescriptorSet(descriptorSet);
323}
324
325// ********************************************************************************************************************
326// ********************************************************************************************************************
327// ********************************************************************************************************************
328// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600329#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500330TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
331{
332 vk_testing::Fence testFence;
333 VK_DBG_MSG_TYPE msgType;
334 std::string msgString;
335
336 VkFenceCreateInfo fenceInfo = {};
337 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
338 fenceInfo.pNext = NULL;
339 fenceInfo.flags = 0;
340
341 ASSERT_NO_FATAL_FAILURE(InitState());
342 ASSERT_NO_FATAL_FAILURE(InitViewport());
343 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
344
345 VkCommandBufferObj cmdBuffer(m_device);
346 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
347
348 BeginCommandBuffer(cmdBuffer);
349 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
350 EndCommandBuffer(cmdBuffer);
351
352 testFence.init(*m_device, fenceInfo);
353
354 // Bypass framework since it does the waits automatically
355 VkResult err = VK_SUCCESS;
356 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
357 ASSERT_VK_SUCCESS( err );
358
359 m_errorMonitor->ClearState();
360 // Introduce failure by calling begin again before checking fence
361 vkResetCommandBuffer(cmdBuffer.obj());
362
363 msgType = m_errorMonitor->GetState(&msgString);
364 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
365 if (!strstr(msgString.c_str(),"Resetting CB")) {
366 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
367 }
368}
369
370TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
371{
372 vk_testing::Fence testFence;
373 VK_DBG_MSG_TYPE msgType;
374 std::string msgString;
375
376 VkFenceCreateInfo fenceInfo = {};
377 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
378 fenceInfo.pNext = NULL;
379 fenceInfo.flags = 0;
380
381 ASSERT_NO_FATAL_FAILURE(InitState());
382 ASSERT_NO_FATAL_FAILURE(InitViewport());
383 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
384
385 VkCommandBufferObj cmdBuffer(m_device);
386 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
387
388 BeginCommandBuffer(cmdBuffer);
389 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
390 EndCommandBuffer(cmdBuffer);
391
392 testFence.init(*m_device, fenceInfo);
393
394 // Bypass framework since it does the waits automatically
395 VkResult err = VK_SUCCESS;
396 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
397 ASSERT_VK_SUCCESS( err );
398
399 m_errorMonitor->ClearState();
400 // Introduce failure by calling begin again before checking fence
401 BeginCommandBuffer(cmdBuffer);
402
403 msgType = m_errorMonitor->GetState(&msgString);
404 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
405 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
406 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
407 }
408}
409
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500410TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
411{
412 VK_DBG_MSG_TYPE msgType;
413 std::string msgString;
414 VkResult err;
415
416 ASSERT_NO_FATAL_FAILURE(InitState());
417 m_errorMonitor->ClearState();
418
419 // Create an image, allocate memory, free it, and then try to bind it
420 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500421 VkDeviceMemory mem;
422 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500423
424 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
425 const int32_t tex_width = 32;
426 const int32_t tex_height = 32;
427 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500428
429 const VkImageCreateInfo image_create_info = {
430 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
431 .pNext = NULL,
432 .imageType = VK_IMAGE_TYPE_2D,
433 .format = tex_format,
434 .extent = { tex_width, tex_height, 1 },
435 .mipLevels = 1,
436 .arraySize = 1,
437 .samples = 1,
438 .tiling = VK_IMAGE_TILING_LINEAR,
439 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
440 .flags = 0,
441 };
442 VkMemoryAllocInfo mem_alloc = {
443 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
444 .pNext = NULL,
445 .allocationSize = 0,
446 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
447 .memProps = 0,
448 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
449 };
450
451 err = vkCreateImage(m_device->device(), &image_create_info, &image);
452 ASSERT_VK_SUCCESS(err);
453
454 err = vkGetObjectInfo(m_device->device(),
455 VK_OBJECT_TYPE_IMAGE,
456 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500457 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
458 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500459 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500460 ASSERT_VK_SUCCESS(err);
461
Mark Lobodzinski23182612015-05-29 09:32:35 -0500462 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500463
464 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500465 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500466 ASSERT_VK_SUCCESS(err);
467
468 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500469 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500470 ASSERT_VK_SUCCESS(err);
471
472 // Map memory as if to initialize the image
473 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500474 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500475
476 msgType = m_errorMonitor->GetState(&msgString);
477 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to map memory not visible to CPU";
478 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
479 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
480 }
481}
482
483TEST_F(VkLayerTest, BindInvalidMemory)
484{
485 VK_DBG_MSG_TYPE msgType;
486 std::string msgString;
487 VkResult err;
488
489 ASSERT_NO_FATAL_FAILURE(InitState());
490 m_errorMonitor->ClearState();
491
492 // Create an image, allocate memory, free it, and then try to bind it
493 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500494 VkDeviceMemory mem;
495 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500496
497 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
498 const int32_t tex_width = 32;
499 const int32_t tex_height = 32;
500 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500501
502 const VkImageCreateInfo image_create_info = {
503 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
504 .pNext = NULL,
505 .imageType = VK_IMAGE_TYPE_2D,
506 .format = tex_format,
507 .extent = { tex_width, tex_height, 1 },
508 .mipLevels = 1,
509 .arraySize = 1,
510 .samples = 1,
511 .tiling = VK_IMAGE_TILING_LINEAR,
512 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
513 .flags = 0,
514 };
515 VkMemoryAllocInfo mem_alloc = {
516 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
517 .pNext = NULL,
518 .allocationSize = 0,
519 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
520 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
521 };
522
523 err = vkCreateImage(m_device->device(), &image_create_info, &image);
524 ASSERT_VK_SUCCESS(err);
525
526 err = vkGetObjectInfo(m_device->device(),
527 VK_OBJECT_TYPE_IMAGE,
528 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500529 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
530 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500531 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500532 ASSERT_VK_SUCCESS(err);
533
Mark Lobodzinski23182612015-05-29 09:32:35 -0500534 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500535
536 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500537 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500538 ASSERT_VK_SUCCESS(err);
539
540 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500541 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500542 ASSERT_VK_SUCCESS(err);
543
544 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500545 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500546 ASSERT_VK_SUCCESS(err);
547
548 msgType = m_errorMonitor->GetState(&msgString);
549 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 -0500550 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500551 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
552 }
553}
554
555TEST_F(VkLayerTest, FreeBoundMemory)
556{
557 VK_DBG_MSG_TYPE msgType;
558 std::string msgString;
559 VkResult err;
560
561 ASSERT_NO_FATAL_FAILURE(InitState());
562 m_errorMonitor->ClearState();
563
564 // Create an image, allocate memory, free it, and then try to bind it
565 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500566 VkDeviceMemory mem;
567 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500568
569 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
570 const int32_t tex_width = 32;
571 const int32_t tex_height = 32;
572 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500573
574 const VkImageCreateInfo image_create_info = {
575 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
576 .pNext = NULL,
577 .imageType = VK_IMAGE_TYPE_2D,
578 .format = tex_format,
579 .extent = { tex_width, tex_height, 1 },
580 .mipLevels = 1,
581 .arraySize = 1,
582 .samples = 1,
583 .tiling = VK_IMAGE_TILING_LINEAR,
584 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
585 .flags = 0,
586 };
587 VkMemoryAllocInfo mem_alloc = {
588 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
589 .pNext = NULL,
590 .allocationSize = 0,
591 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
592 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
593 };
594
595 err = vkCreateImage(m_device->device(), &image_create_info, &image);
596 ASSERT_VK_SUCCESS(err);
597
598 err = vkGetObjectInfo(m_device->device(),
599 VK_OBJECT_TYPE_IMAGE,
600 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500601 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
602 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500603 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500604 ASSERT_VK_SUCCESS(err);
605
Mark Lobodzinski23182612015-05-29 09:32:35 -0500606 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500607
608 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500609 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500610 ASSERT_VK_SUCCESS(err);
611
612 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500613 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500614 ASSERT_VK_SUCCESS(err);
615
616 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500617 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500618 ASSERT_VK_SUCCESS(err);
619
620 msgType = m_errorMonitor->GetState(&msgString);
621 ASSERT_EQ(msgType, VK_DBG_MSG_WARNING) << "Did not receive an warning while tring to free bound memory";
622 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
623 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
624 }
625}
626
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500627TEST_F(VkLayerTest, RebindMemory)
628{
629 VK_DBG_MSG_TYPE msgType;
630 std::string msgString;
631 VkResult err;
632
633 ASSERT_NO_FATAL_FAILURE(InitState());
634 m_errorMonitor->ClearState();
635
636 // Create an image, allocate memory, free it, and then try to bind it
637 VkImage image;
638 VkDeviceMemory mem1;
639 VkDeviceMemory mem2;
640 VkMemoryRequirements mem_reqs;
641
642 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
643 const int32_t tex_width = 32;
644 const int32_t tex_height = 32;
645 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
646
647 const VkImageCreateInfo image_create_info = {
648 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
649 .pNext = NULL,
650 .imageType = VK_IMAGE_TYPE_2D,
651 .format = tex_format,
652 .extent = { tex_width, tex_height, 1 },
653 .mipLevels = 1,
654 .arraySize = 1,
655 .samples = 1,
656 .tiling = VK_IMAGE_TILING_LINEAR,
657 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
658 .flags = 0,
659 };
660 VkMemoryAllocInfo mem_alloc = {
661 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
662 .pNext = NULL,
663 .allocationSize = 0,
664 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
665 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
666 };
667
668 err = vkCreateImage(m_device->device(), &image_create_info, &image);
669 ASSERT_VK_SUCCESS(err);
670
671 err = vkGetObjectInfo(m_device->device(),
672 VK_OBJECT_TYPE_IMAGE,
673 image,
674 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
675 &mem_reqs_size,
676 &mem_reqs);
677 ASSERT_VK_SUCCESS(err);
678
679 mem_alloc.allocationSize = mem_reqs.size;
680
681 // allocate 2 memory objects
682 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
683 ASSERT_VK_SUCCESS(err);
684 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
685 ASSERT_VK_SUCCESS(err);
686
687 // Bind first memory object to Image object
688 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
689 ASSERT_VK_SUCCESS(err);
690
691 // Introduce validation failure, try to bind a different memory object to the same image object
692 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
693 ASSERT_VK_SUCCESS(err);
694
695 msgType = m_errorMonitor->GetState(&msgString);
696 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to rebind an object";
697 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
698 FAIL() << "Error received did not match expected message when rebinding memory to an object";
699 }
700}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500701
702TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
703{
704 VK_DBG_MSG_TYPE msgType;
705 std::string msgString;
706 VkResult err;
707
708 ASSERT_NO_FATAL_FAILURE(InitState());
709 m_errorMonitor->ClearState();
710
711 // Create an image object, allocate memory, destroy the object and then try to bind it
712 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500713 VkDeviceMemory mem;
714 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500715
716 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
717 const int32_t tex_width = 32;
718 const int32_t tex_height = 32;
719 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500720
721 const VkImageCreateInfo image_create_info = {
722 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
723 .pNext = NULL,
724 .imageType = VK_IMAGE_TYPE_2D,
725 .format = tex_format,
726 .extent = { tex_width, tex_height, 1 },
727 .mipLevels = 1,
728 .arraySize = 1,
729 .samples = 1,
730 .tiling = VK_IMAGE_TILING_LINEAR,
731 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
732 .flags = 0,
733 };
734 VkMemoryAllocInfo mem_alloc = {
735 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
736 .pNext = NULL,
737 .allocationSize = 0,
738 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
739 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
740 };
741
742 err = vkCreateImage(m_device->device(), &image_create_info, &image);
743 ASSERT_VK_SUCCESS(err);
744
745 err = vkGetObjectInfo(m_device->device(),
746 VK_OBJECT_TYPE_IMAGE,
747 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500748 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
749 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500750 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500751 ASSERT_VK_SUCCESS(err);
752
Mark Lobodzinski23182612015-05-29 09:32:35 -0500753 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500754
755 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500756 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500757 ASSERT_VK_SUCCESS(err);
758
759 // Introduce validation failure, destroy Image object before binding
760 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
761 ASSERT_VK_SUCCESS(err);
762
763 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500764 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500765 ASSERT_VK_SUCCESS(err);
766
767 msgType = m_errorMonitor->GetState(&msgString);
768 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 -0500769 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500770 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
771 }
772}
773
Tony Barbour8508b8e2015-04-09 10:48:04 -0600774TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600775{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600776 vk_testing::Fence testFence;
777 VK_DBG_MSG_TYPE msgType;
Tony Barbour30486ea2015-04-07 13:44:53 -0600778 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600779
780 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600781 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
782 fenceInfo.pNext = NULL;
783 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600784
Tony Barbour30486ea2015-04-07 13:44:53 -0600785 ASSERT_NO_FATAL_FAILURE(InitState());
786 ASSERT_NO_FATAL_FAILURE(InitViewport());
787 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
788
Tony Barbour01999182015-04-09 12:58:51 -0600789 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600790 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
791
Tony Barbour8508b8e2015-04-09 10:48:04 -0600792 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600793 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600794 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600795
796 testFence.init(*m_device, fenceInfo);
797 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600798 cmdBuffer.QueueCommandBuffer(testFence.obj());
Tony Barbour30486ea2015-04-07 13:44:53 -0600799 msgType = m_errorMonitor->GetState(&msgString);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600800 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
801 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500802 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600803 }
804
805}
806
807TEST_F(VkLayerTest, ResetUnsignaledFence)
808{
809 vk_testing::Fence testFence;
810 VK_DBG_MSG_TYPE msgType;
811 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600812 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600813 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
814 fenceInfo.pNext = NULL;
815
Tony Barbour8508b8e2015-04-09 10:48:04 -0600816 ASSERT_NO_FATAL_FAILURE(InitState());
817 testFence.init(*m_device, fenceInfo);
818 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600819 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600820 vkResetFences(m_device->device(), 1, fences);
821 msgType = m_errorMonitor->GetState(&msgString);
822 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 -0600823 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500824 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600825 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600826
827}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600828#endif
829#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600830TEST_F(VkLayerTest, WaitForUnsubmittedFence)
831{
832 vk_testing::Fence testFence;
833 VK_DBG_MSG_TYPE msgType;
834 std::string msgString;
835 VkFenceCreateInfo fenceInfo = {};
836 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
837 fenceInfo.pNext = NULL;
838
Tony Barbour54cdd192015-04-22 15:12:07 -0600839 ASSERT_NO_FATAL_FAILURE(InitState());
840 testFence.init(*m_device, fenceInfo);
841 m_errorMonitor->ClearState();
842 vkGetFenceStatus(m_device->device(),testFence.obj());
843 msgType = m_errorMonitor->GetState(&msgString);
844 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error asking for status of unsubmitted fence";
845 if (!strstr(msgString.c_str(),"Status Requested for Unsubmitted Fence")) {
846 FAIL() << "Error received was not Status Requested for Unsubmitted Fence";
847 }
848
849 VkFence fences[1] = {testFence.obj()};
850 m_errorMonitor->ClearState();
851 vkWaitForFences(m_device->device(), 1, fences, VK_TRUE, 0);
852 msgType = m_errorMonitor->GetState(&msgString);
853 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error for waiting for unsubmitted fence";
854 if (!strstr(msgString.c_str(),"Waiting for Unsubmitted Fence")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500855 FAIL() << "Error received was not 'Waiting for Unsubmitted Fence'";
Tony Barbour54cdd192015-04-22 15:12:07 -0600856 }
857}
858
Tony Barbourdb686622015-05-06 09:35:56 -0600859TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
860{
861 VkEventCreateInfo event_info;
862 VkEvent event;
863 VkMemoryRequirements mem_req;
864 size_t data_size = sizeof(mem_req);
865 VK_DBG_MSG_TYPE msgType;
866 std::string msgString;
867 VkResult err;
868
869 ASSERT_NO_FATAL_FAILURE(InitState());
870 memset(&event_info, 0, sizeof(event_info));
871 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
872
873 err = vkCreateEvent(device(), &event_info, &event);
874 ASSERT_VK_SUCCESS(err);
875 m_errorMonitor->ClearState();
876 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
877 &data_size, &mem_req);
878 msgType = m_errorMonitor->GetState(&msgString);
879 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from mismatched types in vkGetObjectInfo";
880 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500881 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600882 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500883}
Tony Barbourdb686622015-05-06 09:35:56 -0600884
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500885TEST_F(VkLayerTest, RasterStateNotBound)
886{
887 VK_DBG_MSG_TYPE msgType;
888 std::string msgString;
889
890 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
891
892 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
893
894 msgType = m_errorMonitor->GetState(&msgString);
895 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
896 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
897 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
898 }
899}
900
901TEST_F(VkLayerTest, ViewportStateNotBound)
902{
903 VK_DBG_MSG_TYPE msgType;
904 std::string msgString;
905 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
906
907 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
908
909 msgType = m_errorMonitor->GetState(&msgString);
910 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
911 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
912 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
913 }
914}
915
916TEST_F(VkLayerTest, ColorBlendStateNotBound)
917{
918 VK_DBG_MSG_TYPE msgType;
919 std::string msgString;
920
921 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
922
923 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
924
925 msgType = m_errorMonitor->GetState(&msgString);
926 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
927 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
928 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
929 }
930}
931
932TEST_F(VkLayerTest, DepthStencilStateNotBound)
933{
934 VK_DBG_MSG_TYPE msgType;
935 std::string msgString;
936
937 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
938
939 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
940
941 msgType = m_errorMonitor->GetState(&msgString);
942 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
943 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
944 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
945 }
Tony Barbourdb686622015-05-06 09:35:56 -0600946}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600947#endif
948#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600949TEST_F(VkLayerTest, PipelineNotBound)
950{
951 // Initiate Draw w/o a PSO bound
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600952 VK_DBG_MSG_TYPE msgType;
953 std::string msgString;
954
955 ASSERT_NO_FATAL_FAILURE(InitState());
956 m_errorMonitor->ClearState();
957 VkCommandBufferObj cmdBuffer(m_device);
958 BeginCommandBuffer(cmdBuffer);
959 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
960 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
961 msgType = m_errorMonitor->GetState(&msgString);
962 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
963 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
964 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
965 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600966}
967
968TEST_F(VkLayerTest, InvalidDescriptorPool)
969{
970 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
971 // The DS check for this is after driver has been called to validate DS internal data struct
972 // Attempt to clear DS Pool with bad object
973/* VK_DBG_MSG_TYPE msgType;
974 std::string msgString;
975 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
976 vkResetDescriptorPool(device(), badPool);
977
978 msgType = m_errorMonitor->GetState(&msgString);
979 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
980 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
981 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
982 }*/
983}
984
985TEST_F(VkLayerTest, InvalidDescriptorSet)
986{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600987 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
988 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600989 // Create a valid cmd buffer
990 // call vkCmdBindDescriptorSets w/ false DS
991}
992
993TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
994{
995 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
996 // The DS check for this is after driver has been called to validate DS internal data struct
997}
998
999TEST_F(VkLayerTest, InvalidPipeline)
1000{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001001 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1002 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001003 // Create a valid cmd buffer
1004 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001005 VK_DBG_MSG_TYPE msgType;
1006 std::string msgString;
1007
1008 ASSERT_NO_FATAL_FAILURE(InitState());
1009 m_errorMonitor->ClearState();
1010 VkCommandBufferObj cmdBuffer(m_device);
1011 BeginCommandBuffer(cmdBuffer);
1012 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
1013 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
1014 msgType = m_errorMonitor->GetState(&msgString);
1015 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
1016 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
1017 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
1018 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001019}
1020
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001021TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001022{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001023 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
1024 VK_DBG_MSG_TYPE msgType;
1025 std::string msgString;
1026 VkResult err;
1027
1028 ASSERT_NO_FATAL_FAILURE(InitState());
1029 m_errorMonitor->ClearState();
1030 VkCommandBufferObj cmdBuffer(m_device);
1031 const VkDescriptorTypeCount ds_type_count = {
1032 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1033 .count = 1,
1034 };
1035 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1036 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1037 .pNext = NULL,
1038 .count = 1,
1039 .pTypeCount = &ds_type_count,
1040 };
1041 VkDescriptorPool ds_pool;
1042 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1043 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001044
1045 const VkDescriptorSetLayoutBinding dsl_binding = {
1046 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001047 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001048 .stageFlags = VK_SHADER_STAGE_ALL,
1049 .pImmutableSamplers = NULL,
1050 };
1051
1052 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1053 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1054 .pNext = NULL,
1055 .count = 1,
1056 .pBinding = &dsl_binding,
1057 };
1058 VkDescriptorSetLayout ds_layout;
1059 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1060 ASSERT_VK_SUCCESS(err);
1061
1062 VkDescriptorSet descriptorSet;
1063 uint32_t ds_count = 0;
1064 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1065 ASSERT_VK_SUCCESS(err);
1066
1067 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1068 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1069 .pNext = NULL,
1070 .descriptorSetCount = 1,
1071 .pSetLayouts = &ds_layout,
1072 };
1073
1074 VkPipelineLayout pipeline_layout;
1075 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1076 ASSERT_VK_SUCCESS(err);
1077
1078 size_t shader_len = strlen(bindStateVertShaderText);
1079 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1080 void* pCode = malloc(codeSize);
1081
1082 /* try version 0 first: VkShaderStage followed by GLSL */
1083 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1084 ((uint32_t *) pCode)[1] = 0;
1085 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1086 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1087
1088 const VkShaderCreateInfo vs_ci = {
1089 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1090 .pNext = NULL,
1091 .codeSize = codeSize,
1092 .pCode = pCode,
1093 .flags = 0,
1094 };
1095 VkShader vs;
1096 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1097 ASSERT_VK_SUCCESS(err);
1098
1099 const VkPipelineShader vs_pipe_shader = {
1100 .stage = VK_SHADER_STAGE_VERTEX,
1101 .shader = vs,
1102 .linkConstBufferCount = 0,
1103 .pLinkConstBufferInfo = NULL,
1104 .pSpecializationInfo = NULL,
1105 };
1106 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1107 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1108 .pNext = NULL,
1109 .shader = vs_pipe_shader,
1110 };
1111 const VkGraphicsPipelineCreateInfo gp_ci = {
1112 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1113 .pNext = &pipe_vs_ci,
1114 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1115 .layout = pipeline_layout,
1116 };
1117
1118 VkPipeline pipeline;
1119 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1120 ASSERT_VK_SUCCESS(err);
1121
1122 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1123 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1124
1125 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1126 m_device->get_device_queue();
1127 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1128
1129 msgType = m_errorMonitor->GetState(&msgString);
1130 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1131 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1132 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1133 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001134}
1135
1136TEST_F(VkLayerTest, InvalidDynamicStateObject)
1137{
1138 // Create a valid cmd buffer
1139 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001140 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1141 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001142}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001143
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001144TEST_F(VkLayerTest, VtxBufferBadIndex)
1145{
1146 // Bind VBO out-of-bounds for given PSO
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001147 VK_DBG_MSG_TYPE msgType;
1148 std::string msgString;
1149 VkResult err;
1150
1151 ASSERT_NO_FATAL_FAILURE(InitState());
1152 m_errorMonitor->ClearState();
1153 VkCommandBufferObj cmdBuffer(m_device);
1154 const VkDescriptorTypeCount ds_type_count = {
1155 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1156 .count = 1,
1157 };
1158 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1159 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1160 .pNext = NULL,
1161 .count = 1,
1162 .pTypeCount = &ds_type_count,
1163 };
1164 VkDescriptorPool ds_pool;
1165 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1166 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001167
1168 const VkDescriptorSetLayoutBinding dsl_binding = {
1169 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001170 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001171 .stageFlags = VK_SHADER_STAGE_ALL,
1172 .pImmutableSamplers = NULL,
1173 };
1174
1175 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1176 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1177 .pNext = NULL,
1178 .count = 1,
1179 .pBinding = &dsl_binding,
1180 };
1181 VkDescriptorSetLayout ds_layout;
1182 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1183 ASSERT_VK_SUCCESS(err);
1184
1185 VkDescriptorSet descriptorSet;
1186 uint32_t ds_count = 0;
1187 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1188 ASSERT_VK_SUCCESS(err);
1189
1190 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1191 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1192 .pNext = NULL,
1193 .descriptorSetCount = 1,
1194 .pSetLayouts = &ds_layout,
1195 };
1196
1197 VkPipelineLayout pipeline_layout;
1198 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1199 ASSERT_VK_SUCCESS(err);
1200
1201 size_t shader_len = strlen(bindStateVertShaderText);
1202 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1203 void* pCode = malloc(codeSize);
1204
1205 /* try version 0 first: VkShaderStage followed by GLSL */
1206 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1207 ((uint32_t *) pCode)[1] = 0;
1208 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1209 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1210
1211 const VkShaderCreateInfo vs_ci = {
1212 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1213 .pNext = NULL,
1214 .codeSize = codeSize,
1215 .pCode = pCode,
1216 .flags = 0,
1217 };
1218 VkShader vs;
1219 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1220
1221 const VkPipelineShader vs_pipe_shader = {
1222 .stage = VK_SHADER_STAGE_VERTEX,
1223 .shader = vs,
1224 .linkConstBufferCount = 0,
1225 .pLinkConstBufferInfo = NULL,
1226 .pSpecializationInfo = NULL,
1227 };
1228 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1229 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1230 .pNext = NULL,
1231 .shader = vs_pipe_shader,
1232 };
1233 const VkGraphicsPipelineCreateInfo gp_ci = {
1234 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1235 .pNext = &pipe_vs_ci,
1236 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1237 .layout = pipeline_layout,
1238 };
1239
1240 VkPipeline pipeline;
1241 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1242 ASSERT_VK_SUCCESS(err);
1243
1244 err= cmdBuffer.BeginCommandBuffer();
1245 ASSERT_VK_SUCCESS(err);
1246 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1247 // Should error before calling to driver so don't care about actual data
1248 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1249
1250 msgType = m_errorMonitor->GetState(&msgString);
1251 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
1252 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1253 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1254 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001255}
1256
1257TEST_F(VkLayerTest, DSTypeMismatch)
1258{
1259 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001260 VK_DBG_MSG_TYPE msgType;
1261 std::string msgString;
1262 VkResult err;
1263
1264 ASSERT_NO_FATAL_FAILURE(InitState());
1265 m_errorMonitor->ClearState();
1266 //VkDescriptorSetObj descriptorSet(m_device);
1267 const VkDescriptorTypeCount ds_type_count = {
1268 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1269 .count = 1,
1270 };
1271 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1272 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1273 .pNext = NULL,
1274 .count = 1,
1275 .pTypeCount = &ds_type_count,
1276 };
1277 VkDescriptorPool ds_pool;
1278 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1279 ASSERT_VK_SUCCESS(err);
1280 const VkDescriptorSetLayoutBinding dsl_binding = {
1281 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001282 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001283 .stageFlags = VK_SHADER_STAGE_ALL,
1284 .pImmutableSamplers = NULL,
1285 };
1286
1287 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1288 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1289 .pNext = NULL,
1290 .count = 1,
1291 .pBinding = &dsl_binding,
1292 };
1293 VkDescriptorSetLayout ds_layout;
1294 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1295 ASSERT_VK_SUCCESS(err);
1296
1297 VkDescriptorSet descriptorSet;
1298 uint32_t ds_count = 0;
1299 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1300 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001301
1302 const VkSamplerCreateInfo sampler_ci = {
1303 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1304 .pNext = NULL,
1305 .magFilter = VK_TEX_FILTER_NEAREST,
1306 .minFilter = VK_TEX_FILTER_NEAREST,
1307 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1308 .addressU = VK_TEX_ADDRESS_CLAMP,
1309 .addressV = VK_TEX_ADDRESS_CLAMP,
1310 .addressW = VK_TEX_ADDRESS_CLAMP,
1311 .mipLodBias = 1.0,
1312 .maxAnisotropy = 1,
1313 .compareOp = VK_COMPARE_OP_NEVER,
1314 .minLod = 1.0,
1315 .maxLod = 1.0,
1316 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1317 };
1318 VkSampler sampler;
1319 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1320 ASSERT_VK_SUCCESS(err);
1321
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001322 VkDescriptorInfo descriptor_info;
1323 memset(&descriptor_info, 0, sizeof(descriptor_info));
1324 descriptor_info.sampler = sampler;
1325
1326 VkWriteDescriptorSet descriptor_write;
1327 memset(&descriptor_write, 0, sizeof(descriptor_write));
1328 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1329 descriptor_write.destSet = descriptorSet;
1330 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001331 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001332 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1333 descriptor_write.pDescriptors = &descriptor_info;
1334
1335 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1336
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001337 msgType = m_errorMonitor->GetState(&msgString);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001338 std::cout << msgString << "\n";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001339 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 +08001340 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1341 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 -06001342 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001343}
1344
1345TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1346{
1347 // For overlapping Update, have arrayIndex exceed that of layout
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001348 VK_DBG_MSG_TYPE msgType;
1349 std::string msgString;
1350 VkResult err;
1351
1352 ASSERT_NO_FATAL_FAILURE(InitState());
1353 m_errorMonitor->ClearState();
1354 //VkDescriptorSetObj descriptorSet(m_device);
1355 const VkDescriptorTypeCount ds_type_count = {
1356 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1357 .count = 1,
1358 };
1359 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1360 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1361 .pNext = NULL,
1362 .count = 1,
1363 .pTypeCount = &ds_type_count,
1364 };
1365 VkDescriptorPool ds_pool;
1366 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1367 ASSERT_VK_SUCCESS(err);
1368 const VkDescriptorSetLayoutBinding dsl_binding = {
1369 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001370 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001371 .stageFlags = VK_SHADER_STAGE_ALL,
1372 .pImmutableSamplers = NULL,
1373 };
1374
1375 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1376 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1377 .pNext = NULL,
1378 .count = 1,
1379 .pBinding = &dsl_binding,
1380 };
1381 VkDescriptorSetLayout ds_layout;
1382 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1383 ASSERT_VK_SUCCESS(err);
1384
1385 VkDescriptorSet descriptorSet;
1386 uint32_t ds_count = 0;
1387 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1388 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001389
1390 const VkSamplerCreateInfo sampler_ci = {
1391 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1392 .pNext = NULL,
1393 .magFilter = VK_TEX_FILTER_NEAREST,
1394 .minFilter = VK_TEX_FILTER_NEAREST,
1395 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1396 .addressU = VK_TEX_ADDRESS_CLAMP,
1397 .addressV = VK_TEX_ADDRESS_CLAMP,
1398 .addressW = VK_TEX_ADDRESS_CLAMP,
1399 .mipLodBias = 1.0,
1400 .maxAnisotropy = 1,
1401 .compareOp = VK_COMPARE_OP_NEVER,
1402 .minLod = 1.0,
1403 .maxLod = 1.0,
1404 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1405 };
1406 VkSampler sampler;
1407 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1408 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001409
1410 VkDescriptorInfo descriptor_info;
1411 memset(&descriptor_info, 0, sizeof(descriptor_info));
1412 descriptor_info.sampler = sampler;
1413
1414 VkWriteDescriptorSet descriptor_write;
1415 memset(&descriptor_write, 0, sizeof(descriptor_write));
1416 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1417 descriptor_write.destSet = descriptorSet;
1418 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1419 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001420 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001421 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1422 descriptor_write.pDescriptors = &descriptor_info;
1423
1424 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1425
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001426 msgType = m_errorMonitor->GetState(&msgString);
1427 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 +08001428 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1429 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 -06001430 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001431}
1432
1433TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1434{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001435 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
1436 VK_DBG_MSG_TYPE msgType;
1437 std::string msgString;
1438 VkResult err;
1439
1440 ASSERT_NO_FATAL_FAILURE(InitState());
1441 m_errorMonitor->ClearState();
1442 //VkDescriptorSetObj descriptorSet(m_device);
1443 const VkDescriptorTypeCount ds_type_count = {
1444 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1445 .count = 1,
1446 };
1447 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1448 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1449 .pNext = NULL,
1450 .count = 1,
1451 .pTypeCount = &ds_type_count,
1452 };
1453 VkDescriptorPool ds_pool;
1454 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1455 ASSERT_VK_SUCCESS(err);
1456 const VkDescriptorSetLayoutBinding dsl_binding = {
1457 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001458 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001459 .stageFlags = VK_SHADER_STAGE_ALL,
1460 .pImmutableSamplers = NULL,
1461 };
1462
1463 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1464 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1465 .pNext = NULL,
1466 .count = 1,
1467 .pBinding = &dsl_binding,
1468 };
1469 VkDescriptorSetLayout ds_layout;
1470 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1471 ASSERT_VK_SUCCESS(err);
1472
1473 VkDescriptorSet descriptorSet;
1474 uint32_t ds_count = 0;
1475 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1476 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001477
1478 const VkSamplerCreateInfo sampler_ci = {
1479 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1480 .pNext = NULL,
1481 .magFilter = VK_TEX_FILTER_NEAREST,
1482 .minFilter = VK_TEX_FILTER_NEAREST,
1483 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1484 .addressU = VK_TEX_ADDRESS_CLAMP,
1485 .addressV = VK_TEX_ADDRESS_CLAMP,
1486 .addressW = VK_TEX_ADDRESS_CLAMP,
1487 .mipLodBias = 1.0,
1488 .maxAnisotropy = 1,
1489 .compareOp = VK_COMPARE_OP_NEVER,
1490 .minLod = 1.0,
1491 .maxLod = 1.0,
1492 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1493 };
1494 VkSampler sampler;
1495 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1496 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001497
1498 VkDescriptorInfo descriptor_info;
1499 memset(&descriptor_info, 0, sizeof(descriptor_info));
1500 descriptor_info.sampler = sampler;
1501
1502 VkWriteDescriptorSet descriptor_write;
1503 memset(&descriptor_write, 0, sizeof(descriptor_write));
1504 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1505 descriptor_write.destSet = descriptorSet;
1506 descriptor_write.destBinding = 2;
1507 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001508 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001509 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1510 descriptor_write.pDescriptors = &descriptor_info;
1511
1512 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1513
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001514 msgType = m_errorMonitor->GetState(&msgString);
1515 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ count too large for layout.";
1516 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1517 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1518 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001519}
1520
1521TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1522{
1523 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001524 VK_DBG_MSG_TYPE msgType;
1525 std::string msgString;
1526 VkResult err;
1527
1528 ASSERT_NO_FATAL_FAILURE(InitState());
1529 m_errorMonitor->ClearState();
1530 //VkDescriptorSetObj descriptorSet(m_device);
1531 const VkDescriptorTypeCount ds_type_count = {
1532 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1533 .count = 1,
1534 };
1535 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1536 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1537 .pNext = NULL,
1538 .count = 1,
1539 .pTypeCount = &ds_type_count,
1540 };
1541 VkDescriptorPool ds_pool;
1542 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1543 ASSERT_VK_SUCCESS(err);
1544 const VkDescriptorSetLayoutBinding dsl_binding = {
1545 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001546 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001547 .stageFlags = VK_SHADER_STAGE_ALL,
1548 .pImmutableSamplers = NULL,
1549 };
1550
1551 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1552 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1553 .pNext = NULL,
1554 .count = 1,
1555 .pBinding = &dsl_binding,
1556 };
1557 VkDescriptorSetLayout ds_layout;
1558 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1559 ASSERT_VK_SUCCESS(err);
1560
1561 VkDescriptorSet descriptorSet;
1562 uint32_t ds_count = 0;
1563 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1564 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001565
1566 const VkSamplerCreateInfo sampler_ci = {
1567 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1568 .pNext = NULL,
1569 .magFilter = VK_TEX_FILTER_NEAREST,
1570 .minFilter = VK_TEX_FILTER_NEAREST,
1571 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1572 .addressU = VK_TEX_ADDRESS_CLAMP,
1573 .addressV = VK_TEX_ADDRESS_CLAMP,
1574 .addressW = VK_TEX_ADDRESS_CLAMP,
1575 .mipLodBias = 1.0,
1576 .maxAnisotropy = 1,
1577 .compareOp = VK_COMPARE_OP_NEVER,
1578 .minLod = 1.0,
1579 .maxLod = 1.0,
1580 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1581 };
1582 VkSampler sampler;
1583 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1584 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001585
1586
1587 VkDescriptorInfo descriptor_info;
1588 memset(&descriptor_info, 0, sizeof(descriptor_info));
1589 descriptor_info.sampler = sampler;
1590
1591 VkWriteDescriptorSet descriptor_write;
1592 memset(&descriptor_write, 0, sizeof(descriptor_write));
1593 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1594 descriptor_write.destSet = descriptorSet;
1595 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001596 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001597 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1598 descriptor_write.pDescriptors = &descriptor_info;
1599
1600 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1601
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001602 msgType = m_errorMonitor->GetState(&msgString);
1603 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ invalid struct type.";
1604 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1605 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1606 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001607}
1608
1609TEST_F(VkLayerTest, NumSamplesMismatch)
1610{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001611 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1612 VK_DBG_MSG_TYPE msgType;
1613 std::string msgString;
1614 VkResult err;
1615
1616 ASSERT_NO_FATAL_FAILURE(InitState());
1617 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1618 m_errorMonitor->ClearState();
1619 VkCommandBufferObj cmdBuffer(m_device);
1620 const VkDescriptorTypeCount ds_type_count = {
1621 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1622 .count = 1,
1623 };
1624 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1625 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1626 .pNext = NULL,
1627 .count = 1,
1628 .pTypeCount = &ds_type_count,
1629 };
1630 VkDescriptorPool ds_pool;
1631 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1632 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001633
1634 const VkDescriptorSetLayoutBinding dsl_binding = {
1635 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001636 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001637 .stageFlags = VK_SHADER_STAGE_ALL,
1638 .pImmutableSamplers = NULL,
1639 };
1640
1641 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1642 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1643 .pNext = NULL,
1644 .count = 1,
1645 .pBinding = &dsl_binding,
1646 };
1647 VkDescriptorSetLayout ds_layout;
1648 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1649 ASSERT_VK_SUCCESS(err);
1650
1651 VkDescriptorSet descriptorSet;
1652 uint32_t ds_count = 0;
1653 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1654 ASSERT_VK_SUCCESS(err);
1655
1656 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1657 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1658 .pNext = NULL,
Tony Barbourd1e95582015-06-03 12:30:49 -06001659 .samples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001660 .multisampleEnable = 1,
1661 .sampleShadingEnable = 0,
1662 .minSampleShading = 1.0,
1663 .sampleMask = 15,
1664 };
1665
1666 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1667 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1668 .pNext = NULL,
1669 .descriptorSetCount = 1,
1670 .pSetLayouts = &ds_layout,
1671 };
1672
1673 VkPipelineLayout pipeline_layout;
1674 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1675 ASSERT_VK_SUCCESS(err);
1676
1677 size_t shader_len = strlen(bindStateVertShaderText);
1678 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1679 void* pCode = malloc(codeSize);
1680
1681 /* try version 0 first: VkShaderStage followed by GLSL */
1682 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1683 ((uint32_t *) pCode)[1] = 0;
1684 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1685 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1686
1687 const VkShaderCreateInfo vs_ci = {
1688 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1689 .pNext = NULL,
1690 .codeSize = codeSize,
1691 .pCode = pCode,
1692 .flags = 0,
1693 };
1694 VkShader vs;
1695 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1696 ASSERT_VK_SUCCESS(err);
1697
1698 const VkPipelineShader vs_pipe_shader = {
1699 .stage = VK_SHADER_STAGE_VERTEX,
1700 .shader = vs,
1701 .linkConstBufferCount = 0,
1702 .pLinkConstBufferInfo = NULL,
1703 .pSpecializationInfo = NULL,
1704 };
1705 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1706 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1707 .pNext = &pipe_ms_state_ci,
1708 .shader = vs_pipe_shader,
1709 };
1710 const VkGraphicsPipelineCreateInfo gp_ci = {
1711 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1712 .pNext = &pipe_vs_ci,
1713 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1714 .layout = pipeline_layout,
1715 };
1716
1717 VkPipeline pipeline;
1718 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1719 ASSERT_VK_SUCCESS(err);
1720
1721 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1722 BeginCommandBuffer(cmdBuffer);
1723 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1724
1725 msgType = m_errorMonitor->GetState(&msgString);
1726 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
1727 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1728 FAIL() << "Error received was not 'Num samples mismatch!...'";
1729 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001730}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001731#endif
1732#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001733#if GTEST_IS_THREADSAFE
1734struct thread_data_struct {
1735 VkCmdBuffer cmdBuffer;
1736 VkEvent event;
1737 bool bailout;
1738};
1739
1740extern "C" void *AddToCommandBuffer(void *arg)
1741{
1742 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1743 std::string msgString;
1744
1745 for (int i = 0; i<10000; i++) {
1746 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1747 if (data->bailout) {
1748 break;
1749 }
1750 }
1751 return NULL;
1752}
1753
1754TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1755{
1756 VK_DBG_MSG_TYPE msgType;
1757 std::string msgString;
1758 pthread_t thread;
1759 pthread_attr_t thread_attr;
1760
1761 ASSERT_NO_FATAL_FAILURE(InitState());
1762 ASSERT_NO_FATAL_FAILURE(InitViewport());
1763 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1764
1765 VkCommandBufferObj cmdBuffer(m_device);
1766
1767 m_errorMonitor->ClearState();
1768 pthread_attr_init(&thread_attr);
1769 BeginCommandBuffer(cmdBuffer);
1770
1771 VkEventCreateInfo event_info;
1772 VkEvent event;
1773 VkMemoryRequirements mem_req;
1774 size_t data_size = sizeof(mem_req);
1775 VkResult err;
1776
1777 memset(&event_info, 0, sizeof(event_info));
1778 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1779
1780 err = vkCreateEvent(device(), &event_info, &event);
1781 ASSERT_VK_SUCCESS(err);
1782
1783 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1784 &data_size, &mem_req);
1785 ASSERT_VK_SUCCESS(err);
1786
1787 VkMemoryAllocInfo mem_info;
1788 VkDeviceMemory event_mem;
1789
1790 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1791
1792 memset(&mem_info, 0, sizeof(mem_info));
1793 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1794 mem_info.allocationSize = mem_req.size;
1795 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1796 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1797 err = vkAllocMemory(device(), &mem_info, &event_mem);
1798 ASSERT_VK_SUCCESS(err);
1799
Mark Lobodzinski23182612015-05-29 09:32:35 -05001800 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001801 ASSERT_VK_SUCCESS(err);
1802
1803 err = vkResetEvent(device(), event);
1804 ASSERT_VK_SUCCESS(err);
1805
1806 struct thread_data_struct data;
1807 data.cmdBuffer = cmdBuffer.obj();
1808 data.event = event;
1809 data.bailout = false;
1810 m_errorMonitor->SetBailout(&data.bailout);
1811 // Add many entries to command buffer from another thread.
1812 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1813 // Add many entries to command buffer from this thread at the same time.
1814 AddToCommandBuffer(&data);
1815 pthread_join(thread, NULL);
1816 EndCommandBuffer(cmdBuffer);
1817
1818 msgType = m_errorMonitor->GetState(&msgString);
1819 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using one VkCommandBufferObj in two threads";
1820 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001821 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001822 }
1823
1824}
1825#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001826#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12001827
1828#if SHADER_CHECKER_TESTS
1829TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
1830{
1831 VK_DBG_MSG_TYPE msgType;
1832 std::string msgString;
1833 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001834 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001835
1836 char const *vsSource =
1837 "#version 140\n"
1838 "#extension GL_ARB_separate_shader_objects: require\n"
1839 "#extension GL_ARB_shading_language_420pack: require\n"
1840 "\n"
1841 "layout(location=0) out float x;\n"
1842 "void main(){\n"
1843 " gl_Position = vec4(1);\n"
1844 " x = 0;\n"
1845 "}\n";
1846 char const *fsSource =
1847 "#version 140\n"
1848 "#extension GL_ARB_separate_shader_objects: require\n"
1849 "#extension GL_ARB_shading_language_420pack: require\n"
1850 "\n"
1851 "layout(location=0) out vec4 color;\n"
1852 "void main(){\n"
1853 " color = vec4(1);\n"
1854 "}\n";
1855
1856 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1857 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1858
1859 VkPipelineObj pipe(m_device);
1860 pipe.AddShader(&vs);
1861 pipe.AddShader(&fs);
1862
1863 VkCommandBufferObj dummyCmd(m_device);
1864 VkDescriptorSetObj descriptorSet(m_device);
1865 descriptorSet.AppendDummy();
1866 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1867
1868 m_errorMonitor->ClearState();
1869 pipe.CreateVKPipeline(descriptorSet);
1870
1871 msgType = m_errorMonitor->GetState(&msgString);
1872
1873 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
1874 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
1875 FAIL() << "Incorrect warning: " << msgString;
1876 }
1877}
Chris Forbes5af3bf22015-05-25 11:13:08 +12001878
Chris Forbes3c10b852015-05-25 11:13:13 +12001879TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
1880{
1881 VK_DBG_MSG_TYPE msgType;
1882 std::string msgString;
1883 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001884 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12001885
1886 char const *vsSource =
1887 "#version 140\n"
1888 "#extension GL_ARB_separate_shader_objects: require\n"
1889 "#extension GL_ARB_shading_language_420pack: require\n"
1890 "\n"
1891 "void main(){\n"
1892 " gl_Position = vec4(1);\n"
1893 "}\n";
1894 char const *fsSource =
1895 "#version 140\n"
1896 "#extension GL_ARB_separate_shader_objects: require\n"
1897 "#extension GL_ARB_shading_language_420pack: require\n"
1898 "\n"
1899 "layout(location=0) in float x;\n"
1900 "layout(location=0) out vec4 color;\n"
1901 "void main(){\n"
1902 " color = vec4(x);\n"
1903 "}\n";
1904
1905 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1906 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1907
1908 VkPipelineObj pipe(m_device);
1909 pipe.AddShader(&vs);
1910 pipe.AddShader(&fs);
1911
1912 VkCommandBufferObj dummyCmd(m_device);
1913 VkDescriptorSetObj descriptorSet(m_device);
1914 descriptorSet.AppendDummy();
1915 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1916
1917 m_errorMonitor->ClearState();
1918 pipe.CreateVKPipeline(descriptorSet);
1919
1920 msgType = m_errorMonitor->GetState(&msgString);
1921
1922 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
1923 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
1924 FAIL() << "Incorrect error: " << msgString;
1925 }
1926}
1927
Chris Forbescc281692015-05-25 11:13:17 +12001928TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
1929{
1930 VK_DBG_MSG_TYPE msgType;
1931 std::string msgString;
1932 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001933 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12001934
1935 char const *vsSource =
1936 "#version 140\n"
1937 "#extension GL_ARB_separate_shader_objects: require\n"
1938 "#extension GL_ARB_shading_language_420pack: require\n"
1939 "\n"
1940 "layout(location=0) out int x;\n"
1941 "void main(){\n"
1942 " x = 0;\n"
1943 " gl_Position = vec4(1);\n"
1944 "}\n";
1945 char const *fsSource =
1946 "#version 140\n"
1947 "#extension GL_ARB_separate_shader_objects: require\n"
1948 "#extension GL_ARB_shading_language_420pack: require\n"
1949 "\n"
1950 "layout(location=0) in float x;\n" /* VS writes int */
1951 "layout(location=0) out vec4 color;\n"
1952 "void main(){\n"
1953 " color = vec4(x);\n"
1954 "}\n";
1955
1956 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1957 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1958
1959 VkPipelineObj pipe(m_device);
1960 pipe.AddShader(&vs);
1961 pipe.AddShader(&fs);
1962
1963 VkCommandBufferObj dummyCmd(m_device);
1964 VkDescriptorSetObj descriptorSet(m_device);
1965 descriptorSet.AppendDummy();
1966 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1967
1968 m_errorMonitor->ClearState();
1969 pipe.CreateVKPipeline(descriptorSet);
1970
1971 msgType = m_errorMonitor->GetState(&msgString);
1972
1973 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
1974 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
1975 FAIL() << "Incorrect error: " << msgString;
1976 }
1977}
1978
Chris Forbes8291c052015-05-25 11:13:28 +12001979TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
1980{
1981 VK_DBG_MSG_TYPE msgType;
1982 std::string msgString;
1983 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001984 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12001985
1986 VkVertexInputBindingDescription input_binding;
1987 memset(&input_binding, 0, sizeof(input_binding));
1988
1989 VkVertexInputAttributeDescription input_attrib;
1990 memset(&input_attrib, 0, sizeof(input_attrib));
1991 input_attrib.format = VK_FORMAT_R32_SFLOAT;
1992
1993 char const *vsSource =
1994 "#version 140\n"
1995 "#extension GL_ARB_separate_shader_objects: require\n"
1996 "#extension GL_ARB_shading_language_420pack: require\n"
1997 "\n"
1998 "void main(){\n"
1999 " gl_Position = vec4(1);\n"
2000 "}\n";
2001 char const *fsSource =
2002 "#version 140\n"
2003 "#extension GL_ARB_separate_shader_objects: require\n"
2004 "#extension GL_ARB_shading_language_420pack: require\n"
2005 "\n"
2006 "layout(location=0) out vec4 color;\n"
2007 "void main(){\n"
2008 " color = vec4(1);\n"
2009 "}\n";
2010
2011 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2012 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2013
2014 VkPipelineObj pipe(m_device);
2015 pipe.AddShader(&vs);
2016 pipe.AddShader(&fs);
2017
2018 pipe.AddVertexInputBindings(&input_binding, 1);
2019 pipe.AddVertexInputAttribs(&input_attrib, 1);
2020
2021 VkCommandBufferObj dummyCmd(m_device);
2022 VkDescriptorSetObj descriptorSet(m_device);
2023 descriptorSet.AppendDummy();
2024 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2025
2026 m_errorMonitor->ClearState();
2027 pipe.CreateVKPipeline(descriptorSet);
2028
2029 msgType = m_errorMonitor->GetState(&msgString);
2030
2031 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
2032 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
2033 FAIL() << "Incorrect warning: " << msgString;
2034 }
2035}
2036
Chris Forbes37367e62015-05-25 11:13:29 +12002037TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
2038{
2039 VK_DBG_MSG_TYPE msgType;
2040 std::string msgString;
2041 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002042 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12002043
2044 char const *vsSource =
2045 "#version 140\n"
2046 "#extension GL_ARB_separate_shader_objects: require\n"
2047 "#extension GL_ARB_shading_language_420pack: require\n"
2048 "\n"
2049 "layout(location=0) in vec4 x;\n" /* not provided */
2050 "void main(){\n"
2051 " gl_Position = x;\n"
2052 "}\n";
2053 char const *fsSource =
2054 "#version 140\n"
2055 "#extension GL_ARB_separate_shader_objects: require\n"
2056 "#extension GL_ARB_shading_language_420pack: require\n"
2057 "\n"
2058 "layout(location=0) out vec4 color;\n"
2059 "void main(){\n"
2060 " color = vec4(1);\n"
2061 "}\n";
2062
2063 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2064 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2065
2066 VkPipelineObj pipe(m_device);
2067 pipe.AddShader(&vs);
2068 pipe.AddShader(&fs);
2069
2070 VkCommandBufferObj dummyCmd(m_device);
2071 VkDescriptorSetObj descriptorSet(m_device);
2072 descriptorSet.AppendDummy();
2073 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2074
2075 m_errorMonitor->ClearState();
2076 pipe.CreateVKPipeline(descriptorSet);
2077
2078 msgType = m_errorMonitor->GetState(&msgString);
2079
2080 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2081 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2082 FAIL() << "Incorrect warning: " << msgString;
2083 }
2084}
2085
Chris Forbesa4b02322015-05-25 11:13:31 +12002086TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2087{
2088 VK_DBG_MSG_TYPE msgType;
2089 std::string msgString;
2090 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002091 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002092
2093 VkVertexInputBindingDescription input_binding;
2094 memset(&input_binding, 0, sizeof(input_binding));
2095
2096 VkVertexInputAttributeDescription input_attrib;
2097 memset(&input_attrib, 0, sizeof(input_attrib));
2098 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2099
2100 char const *vsSource =
2101 "#version 140\n"
2102 "#extension GL_ARB_separate_shader_objects: require\n"
2103 "#extension GL_ARB_shading_language_420pack: require\n"
2104 "\n"
2105 "layout(location=0) in int x;\n" /* attrib provided float */
2106 "void main(){\n"
2107 " gl_Position = vec4(x);\n"
2108 "}\n";
2109 char const *fsSource =
2110 "#version 140\n"
2111 "#extension GL_ARB_separate_shader_objects: require\n"
2112 "#extension GL_ARB_shading_language_420pack: require\n"
2113 "\n"
2114 "layout(location=0) out vec4 color;\n"
2115 "void main(){\n"
2116 " color = vec4(1);\n"
2117 "}\n";
2118
2119 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2120 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2121
2122 VkPipelineObj pipe(m_device);
2123 pipe.AddShader(&vs);
2124 pipe.AddShader(&fs);
2125
2126 pipe.AddVertexInputBindings(&input_binding, 1);
2127 pipe.AddVertexInputAttribs(&input_attrib, 1);
2128
2129 VkCommandBufferObj dummyCmd(m_device);
2130 VkDescriptorSetObj descriptorSet(m_device);
2131 descriptorSet.AppendDummy();
2132 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2133
2134 m_errorMonitor->ClearState();
2135 pipe.CreateVKPipeline(descriptorSet);
2136
2137 msgType = m_errorMonitor->GetState(&msgString);
2138
2139 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2140 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2141 FAIL() << "Incorrect error: " << msgString;
2142 }
2143}
2144
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002145TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2146{
2147 VK_DBG_MSG_TYPE msgType;
2148 std::string msgString;
2149 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002150 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002151
2152 /* Two binding descriptions for binding 0 */
2153 VkVertexInputBindingDescription input_bindings[2];
2154 memset(input_bindings, 0, sizeof(input_bindings));
2155
2156 VkVertexInputAttributeDescription input_attrib;
2157 memset(&input_attrib, 0, sizeof(input_attrib));
2158 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2159
2160 char const *vsSource =
2161 "#version 140\n"
2162 "#extension GL_ARB_separate_shader_objects: require\n"
2163 "#extension GL_ARB_shading_language_420pack: require\n"
2164 "\n"
2165 "layout(location=0) in float x;\n" /* attrib provided float */
2166 "void main(){\n"
2167 " gl_Position = vec4(x);\n"
2168 "}\n";
2169 char const *fsSource =
2170 "#version 140\n"
2171 "#extension GL_ARB_separate_shader_objects: require\n"
2172 "#extension GL_ARB_shading_language_420pack: require\n"
2173 "\n"
2174 "layout(location=0) out vec4 color;\n"
2175 "void main(){\n"
2176 " color = vec4(1);\n"
2177 "}\n";
2178
2179 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2180 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2181
2182 VkPipelineObj pipe(m_device);
2183 pipe.AddShader(&vs);
2184 pipe.AddShader(&fs);
2185
2186 pipe.AddVertexInputBindings(input_bindings, 2);
2187 pipe.AddVertexInputAttribs(&input_attrib, 1);
2188
2189 VkCommandBufferObj dummyCmd(m_device);
2190 VkDescriptorSetObj descriptorSet(m_device);
2191 descriptorSet.AppendDummy();
2192 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2193
2194 m_errorMonitor->ClearState();
2195 pipe.CreateVKPipeline(descriptorSet);
2196
2197 msgType = m_errorMonitor->GetState(&msgString);
2198
2199 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2200 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2201 FAIL() << "Incorrect error: " << msgString;
2202 }
2203}
Chris Forbes4c948702015-05-25 11:13:32 +12002204
Chris Forbesc12ef122015-05-25 11:13:40 +12002205/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2206 * rejects it. */
2207
2208TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2209{
2210 VK_DBG_MSG_TYPE msgType;
2211 std::string msgString;
2212 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002213 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002214
2215 char const *vsSource =
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_Position = vec4(1);\n"
2222 "}\n";
2223 char const *fsSource =
2224 "#version 140\n"
2225 "#extension GL_ARB_separate_shader_objects: require\n"
2226 "#extension GL_ARB_shading_language_420pack: require\n"
2227 "\n"
2228 "void main(){\n"
2229 "}\n";
2230
2231 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2232 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2233
2234 VkPipelineObj pipe(m_device);
2235 pipe.AddShader(&vs);
2236 pipe.AddShader(&fs);
2237
2238 /* implicit CB 0 set up by the test framework, not written */
2239
2240 VkCommandBufferObj dummyCmd(m_device);
2241 VkDescriptorSetObj descriptorSet(m_device);
2242 descriptorSet.AppendDummy();
2243 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2244
2245 m_errorMonitor->ClearState();
2246 pipe.CreateVKPipeline(descriptorSet);
2247
2248 msgType = m_errorMonitor->GetState(&msgString);
2249
2250 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2251 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2252 FAIL() << "Incorrect error: " << msgString;
2253 }
2254}
2255
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002256TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2257{
2258 VK_DBG_MSG_TYPE msgType;
2259 std::string msgString;
2260 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002261 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002262
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 "layout(location=0) out vec4 x;\n"
2277 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2278 "void main(){\n"
2279 " x = vec4(1);\n"
2280 " y = vec4(1);\n"
2281 "}\n";
2282
2283 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2284 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2285
2286 VkPipelineObj pipe(m_device);
2287 pipe.AddShader(&vs);
2288 pipe.AddShader(&fs);
2289
2290 /* implicit CB 0 set up by the test framework */
2291 /* FS writes CB 1, but we don't configure it */
2292
2293 VkCommandBufferObj dummyCmd(m_device);
2294 VkDescriptorSetObj descriptorSet(m_device);
2295 descriptorSet.AppendDummy();
2296 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2297
2298 m_errorMonitor->ClearState();
2299 pipe.CreateVKPipeline(descriptorSet);
2300
2301 msgType = m_errorMonitor->GetState(&msgString);
2302
2303 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
2304 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2305 FAIL() << "Incorrect warning: " << msgString;
2306 }
2307}
2308
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002309TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2310{
2311 VK_DBG_MSG_TYPE msgType;
2312 std::string msgString;
2313 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002314 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002315
2316 char const *vsSource =
2317 "#version 140\n"
2318 "#extension GL_ARB_separate_shader_objects: require\n"
2319 "#extension GL_ARB_shading_language_420pack: require\n"
2320 "\n"
2321 "void main(){\n"
2322 " gl_Position = vec4(1);\n"
2323 "}\n";
2324 char const *fsSource =
2325 "#version 140\n"
2326 "#extension GL_ARB_separate_shader_objects: require\n"
2327 "#extension GL_ARB_shading_language_420pack: require\n"
2328 "\n"
2329 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2330 "void main(){\n"
2331 " x = ivec4(1);\n"
2332 "}\n";
2333
2334 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2335 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2336
2337 VkPipelineObj pipe(m_device);
2338 pipe.AddShader(&vs);
2339 pipe.AddShader(&fs);
2340
2341 /* implicit CB 0 set up by test framework, is UNORM. */
2342
2343 VkCommandBufferObj dummyCmd(m_device);
2344 VkDescriptorSetObj descriptorSet(m_device);
2345 descriptorSet.AppendDummy();
2346 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2347
2348 m_errorMonitor->ClearState();
2349 pipe.CreateVKPipeline(descriptorSet);
2350
2351 msgType = m_errorMonitor->GetState(&msgString);
2352
2353 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2354 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2355 FAIL() << "Incorrect error: " << msgString;
2356 }
2357}
Chris Forbesc2050732015-06-05 14:43:36 +12002358
2359TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2360{
2361 VK_DBG_MSG_TYPE msgType;
2362 std::string msgString;
2363 ASSERT_NO_FATAL_FAILURE(InitState());
2364 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002365 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002366
2367 char const *vsSource =
2368 "#version 140\n"
2369 "#extension GL_ARB_separate_shader_objects: require\n"
2370 "#extension GL_ARB_shading_language_420pack: require\n"
2371 "\n"
2372 "void main(){\n"
2373 " gl_Position = vec4(1);\n"
2374 "}\n";
2375 char const *fsSource =
2376 "#version 140\n"
2377 "#extension GL_ARB_separate_shader_objects: require\n"
2378 "#extension GL_ARB_shading_language_420pack: require\n"
2379 "\n"
2380 "layout(location=0) out vec4 x;\n"
2381 "void main(){\n"
2382 " x = vec4(1);\n"
2383 "}\n";
2384
2385 m_errorMonitor->ClearState();
2386
2387 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2388 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2389
2390
2391 VkPipelineObj pipe(m_device);
2392 pipe.AddShader(&vs);
2393 pipe.AddShader(&fs);
2394
2395 /* implicit CB 0 set up by test framework, is UNORM. */
2396
2397 VkCommandBufferObj dummyCmd(m_device);
2398 VkDescriptorSetObj descriptorSet(m_device);
2399 descriptorSet.AppendDummy();
2400 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2401
2402 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2403 /* pipeline creation should have succeeded */
2404 ASSERT_EQ(VK_SUCCESS, res);
2405
2406 /* should have emitted a warning: the shader is not SPIRV, so we're
2407 * not going to be able to analyze it */
2408 msgType = m_errorMonitor->GetState(&msgString);
2409 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
2410 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2411 FAIL() << "Incorrect warning: " << msgString;
2412 }
2413}
Chris Forbes01c9db72015-06-04 09:25:25 +12002414#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002415
Tony Barbour30486ea2015-04-07 13:44:53 -06002416int main(int argc, char **argv) {
2417 int result;
2418
2419 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002420 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002421
2422 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2423
2424 result = RUN_ALL_TESTS();
2425
Tony Barbour01999182015-04-09 12:58:51 -06002426 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002427 return result;
2428}