blob: 4d21434c216ff80d135bd3e6a7bf3c11420a97d4 [file] [log] [blame]
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001#include <vulkan.h>
2#include <vkDbg.h>
Tony Barbour30486ea2015-04-07 13:44:53 -06003#include "gtest-1.7.0/include/gtest/gtest.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06004#include "vkrenderframework.h"
Mark Lobodzinskia910dc82015-05-14 14:30:48 -05005#include "layers_config.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06006
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05007#define GLM_FORCE_RADIANS
8#include "glm/glm.hpp"
9#include <glm/gtc/matrix_transform.hpp>
10
Tobin Ehlis57e6a612015-05-26 16:11:58 -060011#define MEM_TRACKER_TESTS 1
12#define OBJ_TRACKER_TESTS 1
13#define DRAW_STATE_TESTS 1
14#define THREADING_TESTS 1
Chris Forbes5af3bf22015-05-25 11:13:08 +120015#define SHADER_CHECKER_TESTS 1
Tobin Ehlis57e6a612015-05-26 16:11:58 -060016
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050017//--------------------------------------------------------------------------------------
18// Mesh and VertexFormat Data
19//--------------------------------------------------------------------------------------
20struct Vertex
21{
22 float posX, posY, posZ, posW; // Position data
23 float r, g, b, a; // Color
24};
25
26#define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
27
28typedef enum _BsoFailSelect {
29 BsoFailNone = 0x00000000,
30 BsoFailRaster = 0x00000001,
31 BsoFailViewport = 0x00000002,
32 BsoFailColorBlend = 0x00000004,
33 BsoFailDepthStencil = 0x00000008,
34} BsoFailSelect;
35
36struct vktriangle_vs_uniform {
37 // Must start with MVP
38 float mvp[4][4];
39 float position[3][4];
40 float color[3][4];
41};
42
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050043static const char bindStateVertShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050044 "#version 130\n"
45 "vec2 vertices[3];\n"
46 "void main() {\n"
47 " vertices[0] = vec2(-1.0, -1.0);\n"
48 " vertices[1] = vec2( 1.0, -1.0);\n"
49 " vertices[2] = vec2( 0.0, 1.0);\n"
50 " gl_Position = vec4(vertices[gl_VertexID % 3], 0.0, 1.0);\n"
51 "}\n";
52
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050053static const char bindStateFragShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050054 "#version 130\n"
55 "void main() {\n"
56 " gl_FragColor = vec4(0,1,0,1);\n"
57 "}\n";
58
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060059void VKAPI myDbgFunc(
60 VK_DBG_MSG_TYPE msgType,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060061 VkValidationLevel validationLevel,
Mike Stroyan230e6252015-04-17 12:36:38 -060062 VkObject srcObject,
Tony Barbour30486ea2015-04-07 13:44:53 -060063 size_t location,
64 int32_t msgCode,
65 const char* pMsg,
66 void* pUserData);
67
68class ErrorMonitor {
69public:
Tony Barbour0c1bdc62015-04-29 17:34:29 -060070 ErrorMonitor()
Tony Barbour30486ea2015-04-07 13:44:53 -060071 {
Mike Stroyan09aae812015-05-12 16:00:45 -060072 pthread_mutexattr_t attr;
73 pthread_mutexattr_init(&attr);
74 pthread_mutex_init(&m_mutex, &attr);
75 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060076 m_msgType = VK_DBG_MSG_UNKNOWN;
Mike Stroyan09aae812015-05-12 16:00:45 -060077 m_bailout = NULL;
78 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060079 }
80 void ClearState()
81 {
Mike Stroyan09aae812015-05-12 16:00:45 -060082 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060083 m_msgType = VK_DBG_MSG_UNKNOWN;
Tony Barbour30486ea2015-04-07 13:44:53 -060084 m_msgString.clear();
Mike Stroyan09aae812015-05-12 16:00:45 -060085 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060086 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060087 VK_DBG_MSG_TYPE GetState(std::string *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060088 {
Mike Stroyan09aae812015-05-12 16:00:45 -060089 pthread_mutex_lock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060090 *msgString = m_msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -060091 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060092 return m_msgType;
93 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060094 void SetState(VK_DBG_MSG_TYPE msgType, const char *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060095 {
Mike Stroyan09aae812015-05-12 16:00:45 -060096 pthread_mutex_lock(&m_mutex);
97 if (m_bailout != NULL) {
98 *m_bailout = true;
99 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600100 m_msgType = msgType;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600101 m_msgString.reserve(strlen(msgString));
102 m_msgString = msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -0600103 pthread_mutex_unlock(&m_mutex);
104 }
105 void SetBailout(bool *bailout)
106 {
107 m_bailout = bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600108 }
109
110private:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600111 VK_DBG_MSG_TYPE m_msgType;
Mike Stroyan09aae812015-05-12 16:00:45 -0600112 std::string m_msgString;
113 pthread_mutex_t m_mutex;
114 bool* m_bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600115};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500116
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600117void VKAPI myDbgFunc(
Mike Stroyan230e6252015-04-17 12:36:38 -0600118 VK_DBG_MSG_TYPE msgType,
119 VkValidationLevel validationLevel,
120 VkObject srcObject,
Tony Barbour30486ea2015-04-07 13:44:53 -0600121 size_t location,
122 int32_t msgCode,
123 const char* pMsg,
124 void* pUserData)
125{
Tony Barbour8508b8e2015-04-09 10:48:04 -0600126 if (msgType == VK_DBG_MSG_WARNING || msgType == VK_DBG_MSG_ERROR) {
127 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
128 errMonitor->SetState(msgType, pMsg);
129 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600130}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500131
Tony Barbour01999182015-04-09 12:58:51 -0600132class VkLayerTest : public VkRenderFramework
Tony Barbour30486ea2015-04-07 13:44:53 -0600133{
134public:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600135 VkResult BeginCommandBuffer(VkCommandBufferObj &cmdBuffer);
136 VkResult EndCommandBuffer(VkCommandBufferObj &cmdBuffer);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500137 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
138 void GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask);
Tony Barbour30486ea2015-04-07 13:44:53 -0600139
140protected:
Tony Barbour01999182015-04-09 12:58:51 -0600141 VkMemoryRefManager m_memoryRefManager;
142 ErrorMonitor *m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600143
144 virtual void SetUp() {
Chris Forbesd0f3f442015-05-25 11:13:00 +1200145 const char *extension_names[] = {"MemTracker", "ObjectTracker", "Threading", "DrawState", "ShaderChecker"};
Mike Stroyan09aae812015-05-12 16:00:45 -0600146 const std::vector<const char *> extensions(extension_names,
147 extension_names + sizeof(extension_names)/sizeof(extension_names[0]));
Tony Barbour950ebc02015-04-23 12:55:36 -0600148
149 size_t extSize = sizeof(uint32_t);
150 uint32_t extCount = 0;
Tony Barbour04ada4a2015-04-23 15:28:27 -0600151 VkResult U_ASSERT_ONLY err;
Tony Barbour950ebc02015-04-23 12:55:36 -0600152 err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount);
153 assert(!err);
154
155 VkExtensionProperties extProp;
156 extSize = sizeof(VkExtensionProperties);
157 bool32_t extFound;
158
Tony Barbour04ada4a2015-04-23 15:28:27 -0600159 for (uint32_t i = 0; i < extensions.size(); i++) {
Tony Barbour950ebc02015-04-23 12:55:36 -0600160 extFound = 0;
161 for (uint32_t j = 0; j < extCount; j++) {
162 err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_PROPERTIES, j, &extSize, &extProp);
Tony Barbour04ada4a2015-04-23 15:28:27 -0600163 assert(!err);
164 if (!strcmp(extensions[i], extProp.extName)) {
Tony Barbour950ebc02015-04-23 12:55:36 -0600165 extFound = 1;
166 break;
167 }
168 }
Tony Barbour04ada4a2015-04-23 15:28:27 -0600169 ASSERT_EQ(extFound, 1) << "ERROR: Cannot find extension named " << extensions[i] << " which is necessary to pass this test";
Tony Barbour950ebc02015-04-23 12:55:36 -0600170 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600171
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500172 // Force layer output level to be >= WARNING so that we catch those messages but ignore others
173 setLayerOptionEnum("MemTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
174 setLayerOptionEnum("ObjectTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
175 setLayerOptionEnum("ThreadingReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600176 setLayerOptionEnum("DrawStateReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Chris Forbesd0f3f442015-05-25 11:13:00 +1200177 setLayerOptionEnum("ShaderCheckerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500178
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600179 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600180 this->app_info.pNext = NULL;
181 this->app_info.pAppName = "layer_tests";
182 this->app_info.appVersion = 1;
183 this->app_info.pEngineName = "unittest";
184 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600185 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600186
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600187 m_errorMonitor = new ErrorMonitor;
188 InitFramework(extensions, myDbgFunc, m_errorMonitor);
189
Tony Barbour30486ea2015-04-07 13:44:53 -0600190 }
191
192 virtual void TearDown() {
193 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600194 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600195 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600196 }
197};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500198
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600199VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600200{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600201 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600202
203 result = cmdBuffer.BeginCommandBuffer();
204
205 /*
206 * For render test all drawing happens in a single render pass
207 * on a single command buffer.
208 */
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600209 if (VK_SUCCESS == result) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600210 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
211 }
212
213 return result;
214}
215
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600216VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600217{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600218 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600219
220 cmdBuffer.EndRenderPass(renderPass());
221
222 result = cmdBuffer.EndCommandBuffer();
223
224 return result;
225}
226
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500227void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
228{
229 // Create identity matrix
230 int i;
231 struct vktriangle_vs_uniform data;
232
233 glm::mat4 Projection = glm::mat4(1.0f);
234 glm::mat4 View = glm::mat4(1.0f);
235 glm::mat4 Model = glm::mat4(1.0f);
236 glm::mat4 MVP = Projection * View * Model;
237 const int matrixSize = sizeof(MVP);
238 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
239
240 memcpy(&data.mvp, &MVP[0][0], matrixSize);
241
242 static const Vertex tri_data[] =
243 {
244 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
245 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
246 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
247 };
248
249 for (i=0; i<3; i++) {
250 data.position[i][0] = tri_data[i].posX;
251 data.position[i][1] = tri_data[i].posY;
252 data.position[i][2] = tri_data[i].posZ;
253 data.position[i][3] = tri_data[i].posW;
254 data.color[i][0] = tri_data[i].r;
255 data.color[i][1] = tri_data[i].g;
256 data.color[i][2] = tri_data[i].b;
257 data.color[i][3] = tri_data[i].a;
258 }
259
260 ASSERT_NO_FATAL_FAILURE(InitState());
261 ASSERT_NO_FATAL_FAILURE(InitViewport());
262
263 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
264
265 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
266 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
267
268 VkPipelineObj pipelineobj(m_device);
269 pipelineobj.AddShader(&vs);
270 pipelineobj.AddShader(&ps);
271
272 VkDescriptorSetObj descriptorSet(m_device);
273 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
274
275 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
276 VkCommandBufferObj cmdBuffer(m_device);
277 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
278
279 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
280
281 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
282
283 // render triangle
284 cmdBuffer.Draw(0, 3, 0, 1);
285
286 // finalize recording of the command buffer
287 EndCommandBuffer(cmdBuffer);
288
289 cmdBuffer.QueueCommandBuffer();
290}
291
292void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
293{
294 if (m_depthStencil->Initialized()) {
295 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
296 } else {
297 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
298 }
299
300 cmdBuffer->PrepareAttachments();
301 if ((failMask & BsoFailRaster) != BsoFailRaster) {
302 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
303 }
304 if ((failMask & BsoFailViewport) != BsoFailViewport) {
305 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
306 }
307 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
308 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
309 }
310 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
311 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
312 }
313 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
314 pipelineobj.CreateVKPipeline(descriptorSet);
315 cmdBuffer->BindPipeline(pipelineobj);
316 cmdBuffer->BindDescriptorSet(descriptorSet);
317}
318
319// ********************************************************************************************************************
320// ********************************************************************************************************************
321// ********************************************************************************************************************
322// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600323#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500324TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
325{
326 vk_testing::Fence testFence;
327 VK_DBG_MSG_TYPE msgType;
328 std::string msgString;
329
330 VkFenceCreateInfo fenceInfo = {};
331 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
332 fenceInfo.pNext = NULL;
333 fenceInfo.flags = 0;
334
335 ASSERT_NO_FATAL_FAILURE(InitState());
336 ASSERT_NO_FATAL_FAILURE(InitViewport());
337 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
338
339 VkCommandBufferObj cmdBuffer(m_device);
340 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
341
342 BeginCommandBuffer(cmdBuffer);
343 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
344 EndCommandBuffer(cmdBuffer);
345
346 testFence.init(*m_device, fenceInfo);
347
348 // Bypass framework since it does the waits automatically
349 VkResult err = VK_SUCCESS;
350 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
351 ASSERT_VK_SUCCESS( err );
352
353 m_errorMonitor->ClearState();
354 // Introduce failure by calling begin again before checking fence
355 vkResetCommandBuffer(cmdBuffer.obj());
356
357 msgType = m_errorMonitor->GetState(&msgString);
358 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
359 if (!strstr(msgString.c_str(),"Resetting CB")) {
360 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
361 }
362}
363
364TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
365{
366 vk_testing::Fence testFence;
367 VK_DBG_MSG_TYPE msgType;
368 std::string msgString;
369
370 VkFenceCreateInfo fenceInfo = {};
371 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
372 fenceInfo.pNext = NULL;
373 fenceInfo.flags = 0;
374
375 ASSERT_NO_FATAL_FAILURE(InitState());
376 ASSERT_NO_FATAL_FAILURE(InitViewport());
377 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
378
379 VkCommandBufferObj cmdBuffer(m_device);
380 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
381
382 BeginCommandBuffer(cmdBuffer);
383 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
384 EndCommandBuffer(cmdBuffer);
385
386 testFence.init(*m_device, fenceInfo);
387
388 // Bypass framework since it does the waits automatically
389 VkResult err = VK_SUCCESS;
390 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
391 ASSERT_VK_SUCCESS( err );
392
393 m_errorMonitor->ClearState();
394 // Introduce failure by calling begin again before checking fence
395 BeginCommandBuffer(cmdBuffer);
396
397 msgType = m_errorMonitor->GetState(&msgString);
398 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
399 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
400 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
401 }
402}
403
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500404TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
405{
406 VK_DBG_MSG_TYPE msgType;
407 std::string msgString;
408 VkResult err;
409
410 ASSERT_NO_FATAL_FAILURE(InitState());
411 m_errorMonitor->ClearState();
412
413 // Create an image, allocate memory, free it, and then try to bind it
414 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500415 VkDeviceMemory mem;
416 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500417
418 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
419 const int32_t tex_width = 32;
420 const int32_t tex_height = 32;
421 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500422
423 const VkImageCreateInfo image_create_info = {
424 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
425 .pNext = NULL,
426 .imageType = VK_IMAGE_TYPE_2D,
427 .format = tex_format,
428 .extent = { tex_width, tex_height, 1 },
429 .mipLevels = 1,
430 .arraySize = 1,
431 .samples = 1,
432 .tiling = VK_IMAGE_TILING_LINEAR,
433 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
434 .flags = 0,
435 };
436 VkMemoryAllocInfo mem_alloc = {
437 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
438 .pNext = NULL,
439 .allocationSize = 0,
440 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
441 .memProps = 0,
442 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
443 };
444
445 err = vkCreateImage(m_device->device(), &image_create_info, &image);
446 ASSERT_VK_SUCCESS(err);
447
448 err = vkGetObjectInfo(m_device->device(),
449 VK_OBJECT_TYPE_IMAGE,
450 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500451 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
452 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500453 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500454 ASSERT_VK_SUCCESS(err);
455
Mark Lobodzinski23182612015-05-29 09:32:35 -0500456 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500457
458 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500459 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500460 ASSERT_VK_SUCCESS(err);
461
462 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500463 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500464 ASSERT_VK_SUCCESS(err);
465
466 // Map memory as if to initialize the image
467 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500468 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500469
470 msgType = m_errorMonitor->GetState(&msgString);
471 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to map memory not visible to CPU";
472 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
473 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
474 }
475}
476
477TEST_F(VkLayerTest, BindInvalidMemory)
478{
479 VK_DBG_MSG_TYPE msgType;
480 std::string msgString;
481 VkResult err;
482
483 ASSERT_NO_FATAL_FAILURE(InitState());
484 m_errorMonitor->ClearState();
485
486 // Create an image, allocate memory, free it, and then try to bind it
487 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500488 VkDeviceMemory mem;
489 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500490
491 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
492 const int32_t tex_width = 32;
493 const int32_t tex_height = 32;
494 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500495
496 const VkImageCreateInfo image_create_info = {
497 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
498 .pNext = NULL,
499 .imageType = VK_IMAGE_TYPE_2D,
500 .format = tex_format,
501 .extent = { tex_width, tex_height, 1 },
502 .mipLevels = 1,
503 .arraySize = 1,
504 .samples = 1,
505 .tiling = VK_IMAGE_TILING_LINEAR,
506 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
507 .flags = 0,
508 };
509 VkMemoryAllocInfo mem_alloc = {
510 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
511 .pNext = NULL,
512 .allocationSize = 0,
513 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
514 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
515 };
516
517 err = vkCreateImage(m_device->device(), &image_create_info, &image);
518 ASSERT_VK_SUCCESS(err);
519
520 err = vkGetObjectInfo(m_device->device(),
521 VK_OBJECT_TYPE_IMAGE,
522 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500523 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
524 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500525 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500526 ASSERT_VK_SUCCESS(err);
527
Mark Lobodzinski23182612015-05-29 09:32:35 -0500528 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500529
530 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500531 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500532 ASSERT_VK_SUCCESS(err);
533
534 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500535 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500536 ASSERT_VK_SUCCESS(err);
537
538 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500539 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500540 ASSERT_VK_SUCCESS(err);
541
542 msgType = m_errorMonitor->GetState(&msgString);
543 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to bind a freed memory object";
544 if (!strstr(msgString.c_str(),"Unable to set object")) {
545 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
546 }
547}
548
549TEST_F(VkLayerTest, FreeBoundMemory)
550{
551 VK_DBG_MSG_TYPE msgType;
552 std::string msgString;
553 VkResult err;
554
555 ASSERT_NO_FATAL_FAILURE(InitState());
556 m_errorMonitor->ClearState();
557
558 // Create an image, allocate memory, free it, and then try to bind it
559 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500560 VkDeviceMemory mem;
561 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500562
563 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
564 const int32_t tex_width = 32;
565 const int32_t tex_height = 32;
566 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500567
568 const VkImageCreateInfo image_create_info = {
569 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
570 .pNext = NULL,
571 .imageType = VK_IMAGE_TYPE_2D,
572 .format = tex_format,
573 .extent = { tex_width, tex_height, 1 },
574 .mipLevels = 1,
575 .arraySize = 1,
576 .samples = 1,
577 .tiling = VK_IMAGE_TILING_LINEAR,
578 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
579 .flags = 0,
580 };
581 VkMemoryAllocInfo mem_alloc = {
582 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
583 .pNext = NULL,
584 .allocationSize = 0,
585 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
586 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
587 };
588
589 err = vkCreateImage(m_device->device(), &image_create_info, &image);
590 ASSERT_VK_SUCCESS(err);
591
592 err = vkGetObjectInfo(m_device->device(),
593 VK_OBJECT_TYPE_IMAGE,
594 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500595 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
596 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500597 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500598 ASSERT_VK_SUCCESS(err);
599
Mark Lobodzinski23182612015-05-29 09:32:35 -0500600 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500601
602 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500603 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500604 ASSERT_VK_SUCCESS(err);
605
606 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500607 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500608 ASSERT_VK_SUCCESS(err);
609
610 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500611 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500612 ASSERT_VK_SUCCESS(err);
613
614 msgType = m_errorMonitor->GetState(&msgString);
615 ASSERT_EQ(msgType, VK_DBG_MSG_WARNING) << "Did not receive an warning while tring to free bound memory";
616 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
617 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
618 }
619}
620
621
622TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
623{
624 VK_DBG_MSG_TYPE msgType;
625 std::string msgString;
626 VkResult err;
627
628 ASSERT_NO_FATAL_FAILURE(InitState());
629 m_errorMonitor->ClearState();
630
631 // Create an image object, allocate memory, destroy the object and then try to bind it
632 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500633 VkDeviceMemory mem;
634 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500635
636 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
637 const int32_t tex_width = 32;
638 const int32_t tex_height = 32;
639 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500640
641 const VkImageCreateInfo image_create_info = {
642 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
643 .pNext = NULL,
644 .imageType = VK_IMAGE_TYPE_2D,
645 .format = tex_format,
646 .extent = { tex_width, tex_height, 1 },
647 .mipLevels = 1,
648 .arraySize = 1,
649 .samples = 1,
650 .tiling = VK_IMAGE_TILING_LINEAR,
651 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
652 .flags = 0,
653 };
654 VkMemoryAllocInfo mem_alloc = {
655 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
656 .pNext = NULL,
657 .allocationSize = 0,
658 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
659 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
660 };
661
662 err = vkCreateImage(m_device->device(), &image_create_info, &image);
663 ASSERT_VK_SUCCESS(err);
664
665 err = vkGetObjectInfo(m_device->device(),
666 VK_OBJECT_TYPE_IMAGE,
667 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500668 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
669 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500670 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500671 ASSERT_VK_SUCCESS(err);
672
Mark Lobodzinski23182612015-05-29 09:32:35 -0500673 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500674
675 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500676 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500677 ASSERT_VK_SUCCESS(err);
678
679 // Introduce validation failure, destroy Image object before binding
680 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
681 ASSERT_VK_SUCCESS(err);
682
683 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500684 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500685 ASSERT_VK_SUCCESS(err);
686
687 msgType = m_errorMonitor->GetState(&msgString);
688 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while binding memory to a destroyed object";
689 if (!strstr(msgString.c_str(),"Unable to set object")) {
690 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
691 }
692}
693
Tony Barbour8508b8e2015-04-09 10:48:04 -0600694TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600695{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600696 vk_testing::Fence testFence;
697 VK_DBG_MSG_TYPE msgType;
Tony Barbour30486ea2015-04-07 13:44:53 -0600698 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600699
700 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600701 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
702 fenceInfo.pNext = NULL;
703 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600704
Tony Barbour30486ea2015-04-07 13:44:53 -0600705 ASSERT_NO_FATAL_FAILURE(InitState());
706 ASSERT_NO_FATAL_FAILURE(InitViewport());
707 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
708
Tony Barbour01999182015-04-09 12:58:51 -0600709 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600710 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
711
Tony Barbour8508b8e2015-04-09 10:48:04 -0600712 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600713 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600714 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600715
716 testFence.init(*m_device, fenceInfo);
717 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600718 cmdBuffer.QueueCommandBuffer(testFence.obj());
Tony Barbour30486ea2015-04-07 13:44:53 -0600719 msgType = m_errorMonitor->GetState(&msgString);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600720 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
721 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500722 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600723 }
724
725}
726
727TEST_F(VkLayerTest, ResetUnsignaledFence)
728{
729 vk_testing::Fence testFence;
730 VK_DBG_MSG_TYPE msgType;
731 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600732 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600733 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
734 fenceInfo.pNext = NULL;
735
Tony Barbour8508b8e2015-04-09 10:48:04 -0600736 ASSERT_NO_FATAL_FAILURE(InitState());
737 testFence.init(*m_device, fenceInfo);
738 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600739 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600740 vkResetFences(m_device->device(), 1, fences);
741 msgType = m_errorMonitor->GetState(&msgString);
742 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 -0600743 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500744 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600745 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600746
747}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600748#endif
749#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600750TEST_F(VkLayerTest, WaitForUnsubmittedFence)
751{
752 vk_testing::Fence testFence;
753 VK_DBG_MSG_TYPE msgType;
754 std::string msgString;
755 VkFenceCreateInfo fenceInfo = {};
756 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
757 fenceInfo.pNext = NULL;
758
Tony Barbour54cdd192015-04-22 15:12:07 -0600759 ASSERT_NO_FATAL_FAILURE(InitState());
760 testFence.init(*m_device, fenceInfo);
761 m_errorMonitor->ClearState();
762 vkGetFenceStatus(m_device->device(),testFence.obj());
763 msgType = m_errorMonitor->GetState(&msgString);
764 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error asking for status of unsubmitted fence";
765 if (!strstr(msgString.c_str(),"Status Requested for Unsubmitted Fence")) {
766 FAIL() << "Error received was not Status Requested for Unsubmitted Fence";
767 }
768
769 VkFence fences[1] = {testFence.obj()};
770 m_errorMonitor->ClearState();
771 vkWaitForFences(m_device->device(), 1, fences, VK_TRUE, 0);
772 msgType = m_errorMonitor->GetState(&msgString);
773 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error for waiting for unsubmitted fence";
774 if (!strstr(msgString.c_str(),"Waiting for Unsubmitted Fence")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500775 FAIL() << "Error received was not 'Waiting for Unsubmitted Fence'";
Tony Barbour54cdd192015-04-22 15:12:07 -0600776 }
777}
778
Tony Barbourdb686622015-05-06 09:35:56 -0600779TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
780{
781 VkEventCreateInfo event_info;
782 VkEvent event;
783 VkMemoryRequirements mem_req;
784 size_t data_size = sizeof(mem_req);
785 VK_DBG_MSG_TYPE msgType;
786 std::string msgString;
787 VkResult err;
788
789 ASSERT_NO_FATAL_FAILURE(InitState());
790 memset(&event_info, 0, sizeof(event_info));
791 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
792
793 err = vkCreateEvent(device(), &event_info, &event);
794 ASSERT_VK_SUCCESS(err);
795 m_errorMonitor->ClearState();
796 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
797 &data_size, &mem_req);
798 msgType = m_errorMonitor->GetState(&msgString);
799 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from mismatched types in vkGetObjectInfo";
800 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500801 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600802 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500803}
Tony Barbourdb686622015-05-06 09:35:56 -0600804
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500805TEST_F(VkLayerTest, RasterStateNotBound)
806{
807 VK_DBG_MSG_TYPE msgType;
808 std::string msgString;
809
810 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
811
812 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
813
814 msgType = m_errorMonitor->GetState(&msgString);
815 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
816 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
817 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
818 }
819}
820
821TEST_F(VkLayerTest, ViewportStateNotBound)
822{
823 VK_DBG_MSG_TYPE msgType;
824 std::string msgString;
825 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
826
827 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
828
829 msgType = m_errorMonitor->GetState(&msgString);
830 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
831 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
832 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
833 }
834}
835
836TEST_F(VkLayerTest, ColorBlendStateNotBound)
837{
838 VK_DBG_MSG_TYPE msgType;
839 std::string msgString;
840
841 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
842
843 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
844
845 msgType = m_errorMonitor->GetState(&msgString);
846 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
847 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
848 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
849 }
850}
851
852TEST_F(VkLayerTest, DepthStencilStateNotBound)
853{
854 VK_DBG_MSG_TYPE msgType;
855 std::string msgString;
856
857 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
858
859 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
860
861 msgType = m_errorMonitor->GetState(&msgString);
862 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
863 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
864 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
865 }
Tony Barbourdb686622015-05-06 09:35:56 -0600866}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600867#endif
868#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600869TEST_F(VkLayerTest, PipelineNotBound)
870{
871 // Initiate Draw w/o a PSO bound
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600872 VK_DBG_MSG_TYPE msgType;
873 std::string msgString;
874
875 ASSERT_NO_FATAL_FAILURE(InitState());
876 m_errorMonitor->ClearState();
877 VkCommandBufferObj cmdBuffer(m_device);
878 BeginCommandBuffer(cmdBuffer);
879 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
880 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
881 msgType = m_errorMonitor->GetState(&msgString);
882 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
883 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
884 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
885 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600886}
887
888TEST_F(VkLayerTest, InvalidDescriptorPool)
889{
890 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
891 // The DS check for this is after driver has been called to validate DS internal data struct
892 // Attempt to clear DS Pool with bad object
893/* VK_DBG_MSG_TYPE msgType;
894 std::string msgString;
895 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
896 vkResetDescriptorPool(device(), badPool);
897
898 msgType = m_errorMonitor->GetState(&msgString);
899 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
900 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
901 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
902 }*/
903}
904
905TEST_F(VkLayerTest, InvalidDescriptorSet)
906{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600907 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
908 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600909 // Create a valid cmd buffer
910 // call vkCmdBindDescriptorSets w/ false DS
911}
912
913TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
914{
915 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
916 // The DS check for this is after driver has been called to validate DS internal data struct
917}
918
919TEST_F(VkLayerTest, InvalidPipeline)
920{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600921 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
922 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600923 // Create a valid cmd buffer
924 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600925 VK_DBG_MSG_TYPE msgType;
926 std::string msgString;
927
928 ASSERT_NO_FATAL_FAILURE(InitState());
929 m_errorMonitor->ClearState();
930 VkCommandBufferObj cmdBuffer(m_device);
931 BeginCommandBuffer(cmdBuffer);
932 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
933 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
934 msgType = m_errorMonitor->GetState(&msgString);
935 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
936 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
937 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
938 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600939}
940
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600941TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600942{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600943 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
944 VK_DBG_MSG_TYPE msgType;
945 std::string msgString;
946 VkResult err;
947
948 ASSERT_NO_FATAL_FAILURE(InitState());
949 m_errorMonitor->ClearState();
950 VkCommandBufferObj cmdBuffer(m_device);
951 const VkDescriptorTypeCount ds_type_count = {
952 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
953 .count = 1,
954 };
955 const VkDescriptorPoolCreateInfo ds_pool_ci = {
956 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
957 .pNext = NULL,
958 .count = 1,
959 .pTypeCount = &ds_type_count,
960 };
961 VkDescriptorPool ds_pool;
962 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
963 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600964
965 const VkDescriptorSetLayoutBinding dsl_binding = {
966 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +0800967 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600968 .stageFlags = VK_SHADER_STAGE_ALL,
969 .pImmutableSamplers = NULL,
970 };
971
972 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
973 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
974 .pNext = NULL,
975 .count = 1,
976 .pBinding = &dsl_binding,
977 };
978 VkDescriptorSetLayout ds_layout;
979 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
980 ASSERT_VK_SUCCESS(err);
981
982 VkDescriptorSet descriptorSet;
983 uint32_t ds_count = 0;
984 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
985 ASSERT_VK_SUCCESS(err);
986
987 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
988 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
989 .pNext = NULL,
990 .descriptorSetCount = 1,
991 .pSetLayouts = &ds_layout,
992 };
993
994 VkPipelineLayout pipeline_layout;
995 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
996 ASSERT_VK_SUCCESS(err);
997
998 size_t shader_len = strlen(bindStateVertShaderText);
999 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1000 void* pCode = malloc(codeSize);
1001
1002 /* try version 0 first: VkShaderStage followed by GLSL */
1003 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1004 ((uint32_t *) pCode)[1] = 0;
1005 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1006 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1007
1008 const VkShaderCreateInfo vs_ci = {
1009 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1010 .pNext = NULL,
1011 .codeSize = codeSize,
1012 .pCode = pCode,
1013 .flags = 0,
1014 };
1015 VkShader vs;
1016 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1017 ASSERT_VK_SUCCESS(err);
1018
1019 const VkPipelineShader vs_pipe_shader = {
1020 .stage = VK_SHADER_STAGE_VERTEX,
1021 .shader = vs,
1022 .linkConstBufferCount = 0,
1023 .pLinkConstBufferInfo = NULL,
1024 .pSpecializationInfo = NULL,
1025 };
1026 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1027 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1028 .pNext = NULL,
1029 .shader = vs_pipe_shader,
1030 };
1031 const VkGraphicsPipelineCreateInfo gp_ci = {
1032 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1033 .pNext = &pipe_vs_ci,
1034 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1035 .layout = pipeline_layout,
1036 };
1037
1038 VkPipeline pipeline;
1039 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1040 ASSERT_VK_SUCCESS(err);
1041
1042 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1043 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1044
1045 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1046 m_device->get_device_queue();
1047 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1048
1049 msgType = m_errorMonitor->GetState(&msgString);
1050 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
1051 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1052 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1053 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001054}
1055
1056TEST_F(VkLayerTest, InvalidDynamicStateObject)
1057{
1058 // Create a valid cmd buffer
1059 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001060 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1061 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001062}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001063
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001064TEST_F(VkLayerTest, VtxBufferBadIndex)
1065{
1066 // Bind VBO out-of-bounds for given PSO
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001067 VK_DBG_MSG_TYPE msgType;
1068 std::string msgString;
1069 VkResult err;
1070
1071 ASSERT_NO_FATAL_FAILURE(InitState());
1072 m_errorMonitor->ClearState();
1073 VkCommandBufferObj cmdBuffer(m_device);
1074 const VkDescriptorTypeCount ds_type_count = {
1075 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1076 .count = 1,
1077 };
1078 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1079 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1080 .pNext = NULL,
1081 .count = 1,
1082 .pTypeCount = &ds_type_count,
1083 };
1084 VkDescriptorPool ds_pool;
1085 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1086 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001087
1088 const VkDescriptorSetLayoutBinding dsl_binding = {
1089 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001090 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001091 .stageFlags = VK_SHADER_STAGE_ALL,
1092 .pImmutableSamplers = NULL,
1093 };
1094
1095 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1096 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1097 .pNext = NULL,
1098 .count = 1,
1099 .pBinding = &dsl_binding,
1100 };
1101 VkDescriptorSetLayout ds_layout;
1102 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1103 ASSERT_VK_SUCCESS(err);
1104
1105 VkDescriptorSet descriptorSet;
1106 uint32_t ds_count = 0;
1107 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1108 ASSERT_VK_SUCCESS(err);
1109
1110 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1111 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1112 .pNext = NULL,
1113 .descriptorSetCount = 1,
1114 .pSetLayouts = &ds_layout,
1115 };
1116
1117 VkPipelineLayout pipeline_layout;
1118 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1119 ASSERT_VK_SUCCESS(err);
1120
1121 size_t shader_len = strlen(bindStateVertShaderText);
1122 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1123 void* pCode = malloc(codeSize);
1124
1125 /* try version 0 first: VkShaderStage followed by GLSL */
1126 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1127 ((uint32_t *) pCode)[1] = 0;
1128 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1129 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1130
1131 const VkShaderCreateInfo vs_ci = {
1132 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1133 .pNext = NULL,
1134 .codeSize = codeSize,
1135 .pCode = pCode,
1136 .flags = 0,
1137 };
1138 VkShader vs;
1139 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1140
1141 const VkPipelineShader vs_pipe_shader = {
1142 .stage = VK_SHADER_STAGE_VERTEX,
1143 .shader = vs,
1144 .linkConstBufferCount = 0,
1145 .pLinkConstBufferInfo = NULL,
1146 .pSpecializationInfo = NULL,
1147 };
1148 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1149 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1150 .pNext = NULL,
1151 .shader = vs_pipe_shader,
1152 };
1153 const VkGraphicsPipelineCreateInfo gp_ci = {
1154 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1155 .pNext = &pipe_vs_ci,
1156 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1157 .layout = pipeline_layout,
1158 };
1159
1160 VkPipeline pipeline;
1161 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1162 ASSERT_VK_SUCCESS(err);
1163
1164 err= cmdBuffer.BeginCommandBuffer();
1165 ASSERT_VK_SUCCESS(err);
1166 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1167 // Should error before calling to driver so don't care about actual data
1168 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1169
1170 msgType = m_errorMonitor->GetState(&msgString);
1171 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
1172 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1173 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1174 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001175}
1176
1177TEST_F(VkLayerTest, DSTypeMismatch)
1178{
1179 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001180 VK_DBG_MSG_TYPE msgType;
1181 std::string msgString;
1182 VkResult err;
1183
1184 ASSERT_NO_FATAL_FAILURE(InitState());
1185 m_errorMonitor->ClearState();
1186 //VkDescriptorSetObj descriptorSet(m_device);
1187 const VkDescriptorTypeCount ds_type_count = {
1188 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1189 .count = 1,
1190 };
1191 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1192 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1193 .pNext = NULL,
1194 .count = 1,
1195 .pTypeCount = &ds_type_count,
1196 };
1197 VkDescriptorPool ds_pool;
1198 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1199 ASSERT_VK_SUCCESS(err);
1200 const VkDescriptorSetLayoutBinding dsl_binding = {
1201 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001202 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001203 .stageFlags = VK_SHADER_STAGE_ALL,
1204 .pImmutableSamplers = NULL,
1205 };
1206
1207 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1208 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1209 .pNext = NULL,
1210 .count = 1,
1211 .pBinding = &dsl_binding,
1212 };
1213 VkDescriptorSetLayout ds_layout;
1214 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1215 ASSERT_VK_SUCCESS(err);
1216
1217 VkDescriptorSet descriptorSet;
1218 uint32_t ds_count = 0;
1219 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1220 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001221
1222 const VkSamplerCreateInfo sampler_ci = {
1223 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1224 .pNext = NULL,
1225 .magFilter = VK_TEX_FILTER_NEAREST,
1226 .minFilter = VK_TEX_FILTER_NEAREST,
1227 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1228 .addressU = VK_TEX_ADDRESS_CLAMP,
1229 .addressV = VK_TEX_ADDRESS_CLAMP,
1230 .addressW = VK_TEX_ADDRESS_CLAMP,
1231 .mipLodBias = 1.0,
1232 .maxAnisotropy = 1,
1233 .compareOp = VK_COMPARE_OP_NEVER,
1234 .minLod = 1.0,
1235 .maxLod = 1.0,
1236 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1237 };
1238 VkSampler sampler;
1239 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1240 ASSERT_VK_SUCCESS(err);
1241
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001242 VkDescriptorInfo descriptor_info;
1243 memset(&descriptor_info, 0, sizeof(descriptor_info));
1244 descriptor_info.sampler = sampler;
1245
1246 VkWriteDescriptorSet descriptor_write;
1247 memset(&descriptor_write, 0, sizeof(descriptor_write));
1248 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1249 descriptor_write.destSet = descriptorSet;
1250 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001251 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001252 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1253 descriptor_write.pDescriptors = &descriptor_info;
1254
1255 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1256
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001257 msgType = m_errorMonitor->GetState(&msgString);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001258 std::cout << msgString << "\n";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001259 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 +08001260 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1261 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 -06001262 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001263}
1264
1265TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1266{
1267 // For overlapping Update, have arrayIndex exceed that of layout
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001268 VK_DBG_MSG_TYPE msgType;
1269 std::string msgString;
1270 VkResult err;
1271
1272 ASSERT_NO_FATAL_FAILURE(InitState());
1273 m_errorMonitor->ClearState();
1274 //VkDescriptorSetObj descriptorSet(m_device);
1275 const VkDescriptorTypeCount ds_type_count = {
1276 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1277 .count = 1,
1278 };
1279 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1280 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1281 .pNext = NULL,
1282 .count = 1,
1283 .pTypeCount = &ds_type_count,
1284 };
1285 VkDescriptorPool ds_pool;
1286 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1287 ASSERT_VK_SUCCESS(err);
1288 const VkDescriptorSetLayoutBinding dsl_binding = {
1289 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001290 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001291 .stageFlags = VK_SHADER_STAGE_ALL,
1292 .pImmutableSamplers = NULL,
1293 };
1294
1295 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1296 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1297 .pNext = NULL,
1298 .count = 1,
1299 .pBinding = &dsl_binding,
1300 };
1301 VkDescriptorSetLayout ds_layout;
1302 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1303 ASSERT_VK_SUCCESS(err);
1304
1305 VkDescriptorSet descriptorSet;
1306 uint32_t ds_count = 0;
1307 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1308 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001309
1310 const VkSamplerCreateInfo sampler_ci = {
1311 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1312 .pNext = NULL,
1313 .magFilter = VK_TEX_FILTER_NEAREST,
1314 .minFilter = VK_TEX_FILTER_NEAREST,
1315 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1316 .addressU = VK_TEX_ADDRESS_CLAMP,
1317 .addressV = VK_TEX_ADDRESS_CLAMP,
1318 .addressW = VK_TEX_ADDRESS_CLAMP,
1319 .mipLodBias = 1.0,
1320 .maxAnisotropy = 1,
1321 .compareOp = VK_COMPARE_OP_NEVER,
1322 .minLod = 1.0,
1323 .maxLod = 1.0,
1324 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1325 };
1326 VkSampler sampler;
1327 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1328 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001329
1330 VkDescriptorInfo descriptor_info;
1331 memset(&descriptor_info, 0, sizeof(descriptor_info));
1332 descriptor_info.sampler = sampler;
1333
1334 VkWriteDescriptorSet descriptor_write;
1335 memset(&descriptor_write, 0, sizeof(descriptor_write));
1336 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1337 descriptor_write.destSet = descriptorSet;
1338 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1339 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001340 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001341 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1342 descriptor_write.pDescriptors = &descriptor_info;
1343
1344 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1345
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001346 msgType = m_errorMonitor->GetState(&msgString);
1347 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 +08001348 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1349 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 -06001350 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001351}
1352
1353TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1354{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001355 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
1356 VK_DBG_MSG_TYPE msgType;
1357 std::string msgString;
1358 VkResult err;
1359
1360 ASSERT_NO_FATAL_FAILURE(InitState());
1361 m_errorMonitor->ClearState();
1362 //VkDescriptorSetObj descriptorSet(m_device);
1363 const VkDescriptorTypeCount ds_type_count = {
1364 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1365 .count = 1,
1366 };
1367 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1368 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1369 .pNext = NULL,
1370 .count = 1,
1371 .pTypeCount = &ds_type_count,
1372 };
1373 VkDescriptorPool ds_pool;
1374 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1375 ASSERT_VK_SUCCESS(err);
1376 const VkDescriptorSetLayoutBinding dsl_binding = {
1377 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001378 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001379 .stageFlags = VK_SHADER_STAGE_ALL,
1380 .pImmutableSamplers = NULL,
1381 };
1382
1383 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1384 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1385 .pNext = NULL,
1386 .count = 1,
1387 .pBinding = &dsl_binding,
1388 };
1389 VkDescriptorSetLayout ds_layout;
1390 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1391 ASSERT_VK_SUCCESS(err);
1392
1393 VkDescriptorSet descriptorSet;
1394 uint32_t ds_count = 0;
1395 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1396 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001397
1398 const VkSamplerCreateInfo sampler_ci = {
1399 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1400 .pNext = NULL,
1401 .magFilter = VK_TEX_FILTER_NEAREST,
1402 .minFilter = VK_TEX_FILTER_NEAREST,
1403 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1404 .addressU = VK_TEX_ADDRESS_CLAMP,
1405 .addressV = VK_TEX_ADDRESS_CLAMP,
1406 .addressW = VK_TEX_ADDRESS_CLAMP,
1407 .mipLodBias = 1.0,
1408 .maxAnisotropy = 1,
1409 .compareOp = VK_COMPARE_OP_NEVER,
1410 .minLod = 1.0,
1411 .maxLod = 1.0,
1412 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1413 };
1414 VkSampler sampler;
1415 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1416 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001417
1418 VkDescriptorInfo descriptor_info;
1419 memset(&descriptor_info, 0, sizeof(descriptor_info));
1420 descriptor_info.sampler = sampler;
1421
1422 VkWriteDescriptorSet descriptor_write;
1423 memset(&descriptor_write, 0, sizeof(descriptor_write));
1424 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1425 descriptor_write.destSet = descriptorSet;
1426 descriptor_write.destBinding = 2;
1427 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001428 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001429 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1430 descriptor_write.pDescriptors = &descriptor_info;
1431
1432 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1433
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001434 msgType = m_errorMonitor->GetState(&msgString);
1435 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ count too large for layout.";
1436 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1437 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1438 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001439}
1440
1441TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1442{
1443 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001444 VK_DBG_MSG_TYPE msgType;
1445 std::string msgString;
1446 VkResult err;
1447
1448 ASSERT_NO_FATAL_FAILURE(InitState());
1449 m_errorMonitor->ClearState();
1450 //VkDescriptorSetObj descriptorSet(m_device);
1451 const VkDescriptorTypeCount ds_type_count = {
1452 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1453 .count = 1,
1454 };
1455 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1456 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1457 .pNext = NULL,
1458 .count = 1,
1459 .pTypeCount = &ds_type_count,
1460 };
1461 VkDescriptorPool ds_pool;
1462 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1463 ASSERT_VK_SUCCESS(err);
1464 const VkDescriptorSetLayoutBinding dsl_binding = {
1465 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001466 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001467 .stageFlags = VK_SHADER_STAGE_ALL,
1468 .pImmutableSamplers = NULL,
1469 };
1470
1471 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1472 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1473 .pNext = NULL,
1474 .count = 1,
1475 .pBinding = &dsl_binding,
1476 };
1477 VkDescriptorSetLayout ds_layout;
1478 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1479 ASSERT_VK_SUCCESS(err);
1480
1481 VkDescriptorSet descriptorSet;
1482 uint32_t ds_count = 0;
1483 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1484 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001485
1486 const VkSamplerCreateInfo sampler_ci = {
1487 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1488 .pNext = NULL,
1489 .magFilter = VK_TEX_FILTER_NEAREST,
1490 .minFilter = VK_TEX_FILTER_NEAREST,
1491 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1492 .addressU = VK_TEX_ADDRESS_CLAMP,
1493 .addressV = VK_TEX_ADDRESS_CLAMP,
1494 .addressW = VK_TEX_ADDRESS_CLAMP,
1495 .mipLodBias = 1.0,
1496 .maxAnisotropy = 1,
1497 .compareOp = VK_COMPARE_OP_NEVER,
1498 .minLod = 1.0,
1499 .maxLod = 1.0,
1500 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1501 };
1502 VkSampler sampler;
1503 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1504 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001505
1506
1507 VkDescriptorInfo descriptor_info;
1508 memset(&descriptor_info, 0, sizeof(descriptor_info));
1509 descriptor_info.sampler = sampler;
1510
1511 VkWriteDescriptorSet descriptor_write;
1512 memset(&descriptor_write, 0, sizeof(descriptor_write));
1513 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1514 descriptor_write.destSet = descriptorSet;
1515 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001516 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001517 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1518 descriptor_write.pDescriptors = &descriptor_info;
1519
1520 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1521
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001522 msgType = m_errorMonitor->GetState(&msgString);
1523 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ invalid struct type.";
1524 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1525 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1526 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001527}
1528
1529TEST_F(VkLayerTest, NumSamplesMismatch)
1530{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001531 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1532 VK_DBG_MSG_TYPE msgType;
1533 std::string msgString;
1534 VkResult err;
1535
1536 ASSERT_NO_FATAL_FAILURE(InitState());
1537 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1538 m_errorMonitor->ClearState();
1539 VkCommandBufferObj cmdBuffer(m_device);
1540 const VkDescriptorTypeCount ds_type_count = {
1541 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1542 .count = 1,
1543 };
1544 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1545 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1546 .pNext = NULL,
1547 .count = 1,
1548 .pTypeCount = &ds_type_count,
1549 };
1550 VkDescriptorPool ds_pool;
1551 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1552 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001553
1554 const VkDescriptorSetLayoutBinding dsl_binding = {
1555 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001556 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001557 .stageFlags = VK_SHADER_STAGE_ALL,
1558 .pImmutableSamplers = NULL,
1559 };
1560
1561 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1562 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1563 .pNext = NULL,
1564 .count = 1,
1565 .pBinding = &dsl_binding,
1566 };
1567 VkDescriptorSetLayout ds_layout;
1568 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1569 ASSERT_VK_SUCCESS(err);
1570
1571 VkDescriptorSet descriptorSet;
1572 uint32_t ds_count = 0;
1573 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1574 ASSERT_VK_SUCCESS(err);
1575
1576 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1577 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1578 .pNext = NULL,
Tony Barbourd1e95582015-06-03 12:30:49 -06001579 .samples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001580 .multisampleEnable = 1,
1581 .sampleShadingEnable = 0,
1582 .minSampleShading = 1.0,
1583 .sampleMask = 15,
1584 };
1585
1586 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1587 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1588 .pNext = NULL,
1589 .descriptorSetCount = 1,
1590 .pSetLayouts = &ds_layout,
1591 };
1592
1593 VkPipelineLayout pipeline_layout;
1594 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1595 ASSERT_VK_SUCCESS(err);
1596
1597 size_t shader_len = strlen(bindStateVertShaderText);
1598 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1599 void* pCode = malloc(codeSize);
1600
1601 /* try version 0 first: VkShaderStage followed by GLSL */
1602 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1603 ((uint32_t *) pCode)[1] = 0;
1604 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1605 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1606
1607 const VkShaderCreateInfo vs_ci = {
1608 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1609 .pNext = NULL,
1610 .codeSize = codeSize,
1611 .pCode = pCode,
1612 .flags = 0,
1613 };
1614 VkShader vs;
1615 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1616 ASSERT_VK_SUCCESS(err);
1617
1618 const VkPipelineShader vs_pipe_shader = {
1619 .stage = VK_SHADER_STAGE_VERTEX,
1620 .shader = vs,
1621 .linkConstBufferCount = 0,
1622 .pLinkConstBufferInfo = NULL,
1623 .pSpecializationInfo = NULL,
1624 };
1625 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1626 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1627 .pNext = &pipe_ms_state_ci,
1628 .shader = vs_pipe_shader,
1629 };
1630 const VkGraphicsPipelineCreateInfo gp_ci = {
1631 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1632 .pNext = &pipe_vs_ci,
1633 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1634 .layout = pipeline_layout,
1635 };
1636
1637 VkPipeline pipeline;
1638 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1639 ASSERT_VK_SUCCESS(err);
1640
1641 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1642 BeginCommandBuffer(cmdBuffer);
1643 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1644
1645 msgType = m_errorMonitor->GetState(&msgString);
1646 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
1647 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1648 FAIL() << "Error received was not 'Num samples mismatch!...'";
1649 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001650}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001651#endif
1652#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001653#if GTEST_IS_THREADSAFE
1654struct thread_data_struct {
1655 VkCmdBuffer cmdBuffer;
1656 VkEvent event;
1657 bool bailout;
1658};
1659
1660extern "C" void *AddToCommandBuffer(void *arg)
1661{
1662 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1663 std::string msgString;
1664
1665 for (int i = 0; i<10000; i++) {
1666 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1667 if (data->bailout) {
1668 break;
1669 }
1670 }
1671 return NULL;
1672}
1673
1674TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1675{
1676 VK_DBG_MSG_TYPE msgType;
1677 std::string msgString;
1678 pthread_t thread;
1679 pthread_attr_t thread_attr;
1680
1681 ASSERT_NO_FATAL_FAILURE(InitState());
1682 ASSERT_NO_FATAL_FAILURE(InitViewport());
1683 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1684
1685 VkCommandBufferObj cmdBuffer(m_device);
1686
1687 m_errorMonitor->ClearState();
1688 pthread_attr_init(&thread_attr);
1689 BeginCommandBuffer(cmdBuffer);
1690
1691 VkEventCreateInfo event_info;
1692 VkEvent event;
1693 VkMemoryRequirements mem_req;
1694 size_t data_size = sizeof(mem_req);
1695 VkResult err;
1696
1697 memset(&event_info, 0, sizeof(event_info));
1698 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1699
1700 err = vkCreateEvent(device(), &event_info, &event);
1701 ASSERT_VK_SUCCESS(err);
1702
1703 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1704 &data_size, &mem_req);
1705 ASSERT_VK_SUCCESS(err);
1706
1707 VkMemoryAllocInfo mem_info;
1708 VkDeviceMemory event_mem;
1709
1710 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1711
1712 memset(&mem_info, 0, sizeof(mem_info));
1713 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1714 mem_info.allocationSize = mem_req.size;
1715 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1716 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1717 err = vkAllocMemory(device(), &mem_info, &event_mem);
1718 ASSERT_VK_SUCCESS(err);
1719
Mark Lobodzinski23182612015-05-29 09:32:35 -05001720 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001721 ASSERT_VK_SUCCESS(err);
1722
1723 err = vkResetEvent(device(), event);
1724 ASSERT_VK_SUCCESS(err);
1725
1726 struct thread_data_struct data;
1727 data.cmdBuffer = cmdBuffer.obj();
1728 data.event = event;
1729 data.bailout = false;
1730 m_errorMonitor->SetBailout(&data.bailout);
1731 // Add many entries to command buffer from another thread.
1732 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1733 // Add many entries to command buffer from this thread at the same time.
1734 AddToCommandBuffer(&data);
1735 pthread_join(thread, NULL);
1736 EndCommandBuffer(cmdBuffer);
1737
1738 msgType = m_errorMonitor->GetState(&msgString);
1739 ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using one VkCommandBufferObj in two threads";
1740 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001741 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001742 }
1743
1744}
1745#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001746#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12001747
1748#if SHADER_CHECKER_TESTS
1749TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
1750{
1751 VK_DBG_MSG_TYPE msgType;
1752 std::string msgString;
1753 ASSERT_NO_FATAL_FAILURE(InitState());
1754 ScopedUseSpv spv(true);
1755
1756 char const *vsSource =
1757 "#version 140\n"
1758 "#extension GL_ARB_separate_shader_objects: require\n"
1759 "#extension GL_ARB_shading_language_420pack: require\n"
1760 "\n"
1761 "layout(location=0) out float x;\n"
1762 "void main(){\n"
1763 " gl_Position = vec4(1);\n"
1764 " x = 0;\n"
1765 "}\n";
1766 char const *fsSource =
1767 "#version 140\n"
1768 "#extension GL_ARB_separate_shader_objects: require\n"
1769 "#extension GL_ARB_shading_language_420pack: require\n"
1770 "\n"
1771 "layout(location=0) out vec4 color;\n"
1772 "void main(){\n"
1773 " color = vec4(1);\n"
1774 "}\n";
1775
1776 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1777 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1778
1779 VkPipelineObj pipe(m_device);
1780 pipe.AddShader(&vs);
1781 pipe.AddShader(&fs);
1782
1783 VkCommandBufferObj dummyCmd(m_device);
1784 VkDescriptorSetObj descriptorSet(m_device);
1785 descriptorSet.AppendDummy();
1786 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1787
1788 m_errorMonitor->ClearState();
1789 pipe.CreateVKPipeline(descriptorSet);
1790
1791 msgType = m_errorMonitor->GetState(&msgString);
1792
1793 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
1794 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
1795 FAIL() << "Incorrect warning: " << msgString;
1796 }
1797}
1798#endif
1799
Chris Forbes3c10b852015-05-25 11:13:13 +12001800TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
1801{
1802 VK_DBG_MSG_TYPE msgType;
1803 std::string msgString;
1804 ASSERT_NO_FATAL_FAILURE(InitState());
1805 ScopedUseSpv spv(true);
1806
1807 char const *vsSource =
1808 "#version 140\n"
1809 "#extension GL_ARB_separate_shader_objects: require\n"
1810 "#extension GL_ARB_shading_language_420pack: require\n"
1811 "\n"
1812 "void main(){\n"
1813 " gl_Position = vec4(1);\n"
1814 "}\n";
1815 char const *fsSource =
1816 "#version 140\n"
1817 "#extension GL_ARB_separate_shader_objects: require\n"
1818 "#extension GL_ARB_shading_language_420pack: require\n"
1819 "\n"
1820 "layout(location=0) in float x;\n"
1821 "layout(location=0) out vec4 color;\n"
1822 "void main(){\n"
1823 " color = vec4(x);\n"
1824 "}\n";
1825
1826 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1827 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1828
1829 VkPipelineObj pipe(m_device);
1830 pipe.AddShader(&vs);
1831 pipe.AddShader(&fs);
1832
1833 VkCommandBufferObj dummyCmd(m_device);
1834 VkDescriptorSetObj descriptorSet(m_device);
1835 descriptorSet.AppendDummy();
1836 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1837
1838 m_errorMonitor->ClearState();
1839 pipe.CreateVKPipeline(descriptorSet);
1840
1841 msgType = m_errorMonitor->GetState(&msgString);
1842
1843 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
1844 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
1845 FAIL() << "Incorrect error: " << msgString;
1846 }
1847}
1848
Chris Forbescc281692015-05-25 11:13:17 +12001849TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
1850{
1851 VK_DBG_MSG_TYPE msgType;
1852 std::string msgString;
1853 ASSERT_NO_FATAL_FAILURE(InitState());
1854 ScopedUseSpv spv(true);
1855
1856 char const *vsSource =
1857 "#version 140\n"
1858 "#extension GL_ARB_separate_shader_objects: require\n"
1859 "#extension GL_ARB_shading_language_420pack: require\n"
1860 "\n"
1861 "layout(location=0) out int x;\n"
1862 "void main(){\n"
1863 " x = 0;\n"
1864 " gl_Position = vec4(1);\n"
1865 "}\n";
1866 char const *fsSource =
1867 "#version 140\n"
1868 "#extension GL_ARB_separate_shader_objects: require\n"
1869 "#extension GL_ARB_shading_language_420pack: require\n"
1870 "\n"
1871 "layout(location=0) in float x;\n" /* VS writes int */
1872 "layout(location=0) out vec4 color;\n"
1873 "void main(){\n"
1874 " color = vec4(x);\n"
1875 "}\n";
1876
1877 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1878 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1879
1880 VkPipelineObj pipe(m_device);
1881 pipe.AddShader(&vs);
1882 pipe.AddShader(&fs);
1883
1884 VkCommandBufferObj dummyCmd(m_device);
1885 VkDescriptorSetObj descriptorSet(m_device);
1886 descriptorSet.AppendDummy();
1887 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1888
1889 m_errorMonitor->ClearState();
1890 pipe.CreateVKPipeline(descriptorSet);
1891
1892 msgType = m_errorMonitor->GetState(&msgString);
1893
1894 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
1895 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
1896 FAIL() << "Incorrect error: " << msgString;
1897 }
1898}
1899
Chris Forbes8291c052015-05-25 11:13:28 +12001900TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
1901{
1902 VK_DBG_MSG_TYPE msgType;
1903 std::string msgString;
1904 ASSERT_NO_FATAL_FAILURE(InitState());
1905 ScopedUseSpv spv(true);
1906
1907 VkVertexInputBindingDescription input_binding;
1908 memset(&input_binding, 0, sizeof(input_binding));
1909
1910 VkVertexInputAttributeDescription input_attrib;
1911 memset(&input_attrib, 0, sizeof(input_attrib));
1912 input_attrib.format = VK_FORMAT_R32_SFLOAT;
1913
1914 char const *vsSource =
1915 "#version 140\n"
1916 "#extension GL_ARB_separate_shader_objects: require\n"
1917 "#extension GL_ARB_shading_language_420pack: require\n"
1918 "\n"
1919 "void main(){\n"
1920 " gl_Position = vec4(1);\n"
1921 "}\n";
1922 char const *fsSource =
1923 "#version 140\n"
1924 "#extension GL_ARB_separate_shader_objects: require\n"
1925 "#extension GL_ARB_shading_language_420pack: require\n"
1926 "\n"
1927 "layout(location=0) out vec4 color;\n"
1928 "void main(){\n"
1929 " color = vec4(1);\n"
1930 "}\n";
1931
1932 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1933 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1934
1935 VkPipelineObj pipe(m_device);
1936 pipe.AddShader(&vs);
1937 pipe.AddShader(&fs);
1938
1939 pipe.AddVertexInputBindings(&input_binding, 1);
1940 pipe.AddVertexInputAttribs(&input_attrib, 1);
1941
1942 VkCommandBufferObj dummyCmd(m_device);
1943 VkDescriptorSetObj descriptorSet(m_device);
1944 descriptorSet.AppendDummy();
1945 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1946
1947 m_errorMonitor->ClearState();
1948 pipe.CreateVKPipeline(descriptorSet);
1949
1950 msgType = m_errorMonitor->GetState(&msgString);
1951
1952 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
1953 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
1954 FAIL() << "Incorrect warning: " << msgString;
1955 }
1956}
1957
Chris Forbes37367e62015-05-25 11:13:29 +12001958TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
1959{
1960 VK_DBG_MSG_TYPE msgType;
1961 std::string msgString;
1962 ASSERT_NO_FATAL_FAILURE(InitState());
1963 ScopedUseSpv spv(true);
1964
1965 char const *vsSource =
1966 "#version 140\n"
1967 "#extension GL_ARB_separate_shader_objects: require\n"
1968 "#extension GL_ARB_shading_language_420pack: require\n"
1969 "\n"
1970 "layout(location=0) in vec4 x;\n" /* not provided */
1971 "void main(){\n"
1972 " gl_Position = x;\n"
1973 "}\n";
1974 char const *fsSource =
1975 "#version 140\n"
1976 "#extension GL_ARB_separate_shader_objects: require\n"
1977 "#extension GL_ARB_shading_language_420pack: require\n"
1978 "\n"
1979 "layout(location=0) out vec4 color;\n"
1980 "void main(){\n"
1981 " color = vec4(1);\n"
1982 "}\n";
1983
1984 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1985 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1986
1987 VkPipelineObj pipe(m_device);
1988 pipe.AddShader(&vs);
1989 pipe.AddShader(&fs);
1990
1991 VkCommandBufferObj dummyCmd(m_device);
1992 VkDescriptorSetObj descriptorSet(m_device);
1993 descriptorSet.AppendDummy();
1994 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1995
1996 m_errorMonitor->ClearState();
1997 pipe.CreateVKPipeline(descriptorSet);
1998
1999 msgType = m_errorMonitor->GetState(&msgString);
2000
2001 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2002 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2003 FAIL() << "Incorrect warning: " << msgString;
2004 }
2005}
2006
Chris Forbesa4b02322015-05-25 11:13:31 +12002007TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2008{
2009 VK_DBG_MSG_TYPE msgType;
2010 std::string msgString;
2011 ASSERT_NO_FATAL_FAILURE(InitState());
2012 ScopedUseSpv spv(true);
2013
2014 VkVertexInputBindingDescription input_binding;
2015 memset(&input_binding, 0, sizeof(input_binding));
2016
2017 VkVertexInputAttributeDescription input_attrib;
2018 memset(&input_attrib, 0, sizeof(input_attrib));
2019 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2020
2021 char const *vsSource =
2022 "#version 140\n"
2023 "#extension GL_ARB_separate_shader_objects: require\n"
2024 "#extension GL_ARB_shading_language_420pack: require\n"
2025 "\n"
2026 "layout(location=0) in int x;\n" /* attrib provided float */
2027 "void main(){\n"
2028 " gl_Position = vec4(x);\n"
2029 "}\n";
2030 char const *fsSource =
2031 "#version 140\n"
2032 "#extension GL_ARB_separate_shader_objects: require\n"
2033 "#extension GL_ARB_shading_language_420pack: require\n"
2034 "\n"
2035 "layout(location=0) out vec4 color;\n"
2036 "void main(){\n"
2037 " color = vec4(1);\n"
2038 "}\n";
2039
2040 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2041 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2042
2043 VkPipelineObj pipe(m_device);
2044 pipe.AddShader(&vs);
2045 pipe.AddShader(&fs);
2046
2047 pipe.AddVertexInputBindings(&input_binding, 1);
2048 pipe.AddVertexInputAttribs(&input_attrib, 1);
2049
2050 VkCommandBufferObj dummyCmd(m_device);
2051 VkDescriptorSetObj descriptorSet(m_device);
2052 descriptorSet.AppendDummy();
2053 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2054
2055 m_errorMonitor->ClearState();
2056 pipe.CreateVKPipeline(descriptorSet);
2057
2058 msgType = m_errorMonitor->GetState(&msgString);
2059
2060 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2061 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2062 FAIL() << "Incorrect error: " << msgString;
2063 }
2064}
2065
Chris Forbes4c948702015-05-25 11:13:32 +12002066TEST_F(VkLayerTest, CreatePipelineFragmentBroadcastWithInteger)
2067{
2068 VK_DBG_MSG_TYPE msgType;
2069 std::string msgString;
2070 ASSERT_NO_FATAL_FAILURE(InitState());
2071 ScopedUseSpv spv(true);
2072
2073 char const *vsSource =
2074 "#version 140\n"
2075 "#extension GL_ARB_separate_shader_objects: require\n"
2076 "#extension GL_ARB_shading_language_420pack: require\n"
2077 "\n"
2078 "void main(){\n"
2079 " gl_Position = vec4(1);\n"
2080 "}\n";
2081 char const *fsSource =
2082 "#version 140\n"
2083 "#extension GL_ARB_separate_shader_objects: require\n"
2084 "#extension GL_ARB_shading_language_420pack: require\n"
2085 "\n"
2086 "void main(){\n"
2087 " gl_FragColor = vec4(1);\n" /* broadcast */
2088 "}\n";
2089
2090 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2091 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2092
2093 VkPipelineObj pipe(m_device);
2094 pipe.AddShader(&vs);
2095 pipe.AddShader(&fs);
2096
2097 VkPipelineCbAttachmentState attach;
2098 memset(&attach, 0, sizeof(attach));
2099 attach.format = VK_FORMAT_R8_UINT; /* not unorm/snorm/float */
2100
2101 pipe.AddColorAttachment(1, &attach);
2102
2103 VkCommandBufferObj dummyCmd(m_device);
2104 VkDescriptorSetObj descriptorSet(m_device);
2105 descriptorSet.AppendDummy();
2106 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2107
2108 m_errorMonitor->ClearState();
2109 pipe.CreateVKPipeline(descriptorSet);
2110
2111 msgType = m_errorMonitor->GetState(&msgString);
2112
2113 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2114 if (!strstr(msgString.c_str(),"CB format should not be SINT or UINT when using broadcast")) {
2115 FAIL() << "Incorrect error: " << msgString;
2116 }
2117}
2118
Chris Forbesc12ef122015-05-25 11:13:40 +12002119/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2120 * rejects it. */
2121
2122TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2123{
2124 VK_DBG_MSG_TYPE msgType;
2125 std::string msgString;
2126 ASSERT_NO_FATAL_FAILURE(InitState());
2127 ScopedUseSpv spv(true);
2128
2129 char const *vsSource =
2130 "#version 140\n"
2131 "#extension GL_ARB_separate_shader_objects: require\n"
2132 "#extension GL_ARB_shading_language_420pack: require\n"
2133 "\n"
2134 "void main(){\n"
2135 " gl_Position = vec4(1);\n"
2136 "}\n";
2137 char const *fsSource =
2138 "#version 140\n"
2139 "#extension GL_ARB_separate_shader_objects: require\n"
2140 "#extension GL_ARB_shading_language_420pack: require\n"
2141 "\n"
2142 "void main(){\n"
2143 "}\n";
2144
2145 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2146 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2147
2148 VkPipelineObj pipe(m_device);
2149 pipe.AddShader(&vs);
2150 pipe.AddShader(&fs);
2151
2152 /* implicit CB 0 set up by the test framework, not written */
2153
2154 VkCommandBufferObj dummyCmd(m_device);
2155 VkDescriptorSetObj descriptorSet(m_device);
2156 descriptorSet.AppendDummy();
2157 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2158
2159 m_errorMonitor->ClearState();
2160 pipe.CreateVKPipeline(descriptorSet);
2161
2162 msgType = m_errorMonitor->GetState(&msgString);
2163
2164 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2165 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2166 FAIL() << "Incorrect error: " << msgString;
2167 }
2168}
2169
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002170TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2171{
2172 VK_DBG_MSG_TYPE msgType;
2173 std::string msgString;
2174 ASSERT_NO_FATAL_FAILURE(InitState());
2175 ScopedUseSpv spv(true);
2176
2177 char const *vsSource =
2178 "#version 140\n"
2179 "#extension GL_ARB_separate_shader_objects: require\n"
2180 "#extension GL_ARB_shading_language_420pack: require\n"
2181 "\n"
2182 "void main(){\n"
2183 " gl_Position = vec4(1);\n"
2184 "}\n";
2185 char const *fsSource =
2186 "#version 140\n"
2187 "#extension GL_ARB_separate_shader_objects: require\n"
2188 "#extension GL_ARB_shading_language_420pack: require\n"
2189 "\n"
2190 "layout(location=0) out vec4 x;\n"
2191 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2192 "void main(){\n"
2193 " x = vec4(1);\n"
2194 " y = vec4(1);\n"
2195 "}\n";
2196
2197 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2198 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2199
2200 VkPipelineObj pipe(m_device);
2201 pipe.AddShader(&vs);
2202 pipe.AddShader(&fs);
2203
2204 /* implicit CB 0 set up by the test framework */
2205 /* FS writes CB 1, but we don't configure it */
2206
2207 VkCommandBufferObj dummyCmd(m_device);
2208 VkDescriptorSetObj descriptorSet(m_device);
2209 descriptorSet.AppendDummy();
2210 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2211
2212 m_errorMonitor->ClearState();
2213 pipe.CreateVKPipeline(descriptorSet);
2214
2215 msgType = m_errorMonitor->GetState(&msgString);
2216
2217 ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
2218 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2219 FAIL() << "Incorrect warning: " << msgString;
2220 }
2221}
2222
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002223TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2224{
2225 VK_DBG_MSG_TYPE msgType;
2226 std::string msgString;
2227 ASSERT_NO_FATAL_FAILURE(InitState());
2228 ScopedUseSpv spv(true);
2229
2230 char const *vsSource =
2231 "#version 140\n"
2232 "#extension GL_ARB_separate_shader_objects: require\n"
2233 "#extension GL_ARB_shading_language_420pack: require\n"
2234 "\n"
2235 "void main(){\n"
2236 " gl_Position = vec4(1);\n"
2237 "}\n";
2238 char const *fsSource =
2239 "#version 140\n"
2240 "#extension GL_ARB_separate_shader_objects: require\n"
2241 "#extension GL_ARB_shading_language_420pack: require\n"
2242 "\n"
2243 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2244 "void main(){\n"
2245 " x = ivec4(1);\n"
2246 "}\n";
2247
2248 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2249 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2250
2251 VkPipelineObj pipe(m_device);
2252 pipe.AddShader(&vs);
2253 pipe.AddShader(&fs);
2254
2255 /* implicit CB 0 set up by test framework, is UNORM. */
2256
2257 VkCommandBufferObj dummyCmd(m_device);
2258 VkDescriptorSetObj descriptorSet(m_device);
2259 descriptorSet.AppendDummy();
2260 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2261
2262 m_errorMonitor->ClearState();
2263 pipe.CreateVKPipeline(descriptorSet);
2264
2265 msgType = m_errorMonitor->GetState(&msgString);
2266
2267 ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
2268 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2269 FAIL() << "Incorrect error: " << msgString;
2270 }
2271}
2272
Tony Barbour30486ea2015-04-07 13:44:53 -06002273int main(int argc, char **argv) {
2274 int result;
2275
2276 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002277 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002278
2279 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2280
2281 result = RUN_ALL_TESTS();
2282
Tony Barbour01999182015-04-09 12:58:51 -06002283 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002284 return result;
2285}