blob: e9cf95869db4072b4a02623d1eefe16e353c30cc [file] [log] [blame]
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001#include <vulkan.h>
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002#include "vk_debug_report_lunarg.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06003#include "gtest-1.7.0/include/gtest/gtest.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06004#include "vkrenderframework.h"
Mark Lobodzinskia910dc82015-05-14 14:30:48 -05005#include "layers_config.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06006
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05007#define GLM_FORCE_RADIANS
8#include "glm/glm.hpp"
9#include <glm/gtc/matrix_transform.hpp>
10
Tobin Ehlis57e6a612015-05-26 16:11:58 -060011#define MEM_TRACKER_TESTS 1
12#define OBJ_TRACKER_TESTS 1
13#define DRAW_STATE_TESTS 1
14#define THREADING_TESTS 1
Chris Forbes5af3bf22015-05-25 11:13:08 +120015#define SHADER_CHECKER_TESTS 1
Tobin Ehlis57e6a612015-05-26 16:11:58 -060016
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050017//--------------------------------------------------------------------------------------
18// Mesh and VertexFormat Data
19//--------------------------------------------------------------------------------------
20struct Vertex
21{
22 float posX, posY, posZ, posW; // Position data
23 float r, g, b, a; // Color
24};
25
26#define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
27
28typedef enum _BsoFailSelect {
29 BsoFailNone = 0x00000000,
30 BsoFailRaster = 0x00000001,
31 BsoFailViewport = 0x00000002,
32 BsoFailColorBlend = 0x00000004,
33 BsoFailDepthStencil = 0x00000008,
34} BsoFailSelect;
35
36struct vktriangle_vs_uniform {
37 // Must start with MVP
38 float mvp[4][4];
39 float position[3][4];
40 float color[3][4];
41};
42
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050043static const char bindStateVertShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050044 "#version 130\n"
45 "vec2 vertices[3];\n"
46 "void main() {\n"
47 " vertices[0] = vec2(-1.0, -1.0);\n"
48 " vertices[1] = vec2( 1.0, -1.0);\n"
49 " vertices[2] = vec2( 0.0, 1.0);\n"
50 " gl_Position = vec4(vertices[gl_VertexID % 3], 0.0, 1.0);\n"
51 "}\n";
52
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050053static const char bindStateFragShaderText[] =
Cody Northrop74a2d2c2015-06-16 17:32:04 -060054 "#version 140\n"
55 "#extension GL_ARB_separate_shader_objects: require\n"
56 "#extension GL_ARB_shading_language_420pack: require\n"
57 "\n"
58 "layout(location = 0) out vec4 uFragColor;\n"
59 "void main(){\n"
60 " uFragColor = vec4(0,1,0,1);\n"
61 "}\n";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050062
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060063static void myDbgFunc(
64 VkFlags msgFlags,
65 VkObjectType objType,
66 VkObject srcObject,
67 size_t location,
68 int32_t msgCode,
69 const char* pLayerPrefix,
70 const char* pMsg,
71 void* pUserData);
Tony Barbour30486ea2015-04-07 13:44:53 -060072
73class ErrorMonitor {
74public:
Tony Barbour0c1bdc62015-04-29 17:34:29 -060075 ErrorMonitor()
Tony Barbour30486ea2015-04-07 13:44:53 -060076 {
Mike Stroyan09aae812015-05-12 16:00:45 -060077 pthread_mutexattr_t attr;
78 pthread_mutexattr_init(&attr);
79 pthread_mutex_init(&m_mutex, &attr);
80 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060081 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Mike Stroyan09aae812015-05-12 16:00:45 -060082 m_bailout = NULL;
83 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060084 }
85 void ClearState()
86 {
Mike Stroyan09aae812015-05-12 16:00:45 -060087 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060088 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -060089 m_msgString.clear();
Mike Stroyan09aae812015-05-12 16:00:45 -060090 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060091 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060092 VkFlags GetState(std::string *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060093 {
Mike Stroyan09aae812015-05-12 16:00:45 -060094 pthread_mutex_lock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060095 *msgString = m_msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -060096 pthread_mutex_unlock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060097 return m_msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -060098 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060099 void SetState(VkFlags msgFlags, const char *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -0600100 {
Mike Stroyan09aae812015-05-12 16:00:45 -0600101 pthread_mutex_lock(&m_mutex);
102 if (m_bailout != NULL) {
103 *m_bailout = true;
104 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600105 m_msgFlags = msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600106 m_msgString.reserve(strlen(msgString));
107 m_msgString = msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -0600108 pthread_mutex_unlock(&m_mutex);
109 }
110 void SetBailout(bool *bailout)
111 {
112 m_bailout = bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600113 }
114
115private:
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600116 VkFlags m_msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -0600117 std::string m_msgString;
118 pthread_mutex_t m_mutex;
119 bool* m_bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600120};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500121
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600122static void myDbgFunc(
123 VkFlags msgFlags,
124 VkObjectType objType,
125 VkObject srcObject,
126 size_t location,
127 int32_t msgCode,
128 const char* pLayerPrefix,
129 const char* pMsg,
130 void* pUserData)
Tony Barbour30486ea2015-04-07 13:44:53 -0600131{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600132 if (msgFlags & (VK_DBG_REPORT_WARN_BIT | VK_DBG_REPORT_ERROR_BIT)) {
Tony Barbour8508b8e2015-04-09 10:48:04 -0600133 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600134 errMonitor->SetState(msgFlags, pMsg);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600135 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600136}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500137
Tony Barbour01999182015-04-09 12:58:51 -0600138class VkLayerTest : public VkRenderFramework
Tony Barbour30486ea2015-04-07 13:44:53 -0600139{
140public:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600141 VkResult BeginCommandBuffer(VkCommandBufferObj &cmdBuffer);
142 VkResult EndCommandBuffer(VkCommandBufferObj &cmdBuffer);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500143 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
144 void GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask);
Tony Barbour30486ea2015-04-07 13:44:53 -0600145
146protected:
Tony Barbour01999182015-04-09 12:58:51 -0600147 VkMemoryRefManager m_memoryRefManager;
148 ErrorMonitor *m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600149
150 virtual void SetUp() {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600151 std::vector<const char *> instance_extension_names;
152 std::vector<const char *> device_extension_names;
Tony Barbour950ebc02015-04-23 12:55:36 -0600153
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600154 instance_extension_names.push_back(DEBUG_REPORT_EXTENSION_NAME);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600155 instance_extension_names.push_back("MemTracker");
156 instance_extension_names.push_back("ObjectTracker");
157 instance_extension_names.push_back("Threading");
158
159 device_extension_names.push_back("MemTracker");
160 device_extension_names.push_back("ObjectTracker");
161 device_extension_names.push_back("Threading");
Tony Barbour30486ea2015-04-07 13:44:53 -0600162
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500163 // Force layer output level to be >= WARNING so that we catch those messages but ignore others
164 setLayerOptionEnum("MemTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
165 setLayerOptionEnum("ObjectTrackerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
166 setLayerOptionEnum("ThreadingReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600167 setLayerOptionEnum("DrawStateReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Chris Forbesd0f3f442015-05-25 11:13:00 +1200168 setLayerOptionEnum("ShaderCheckerReportLevel", "VK_DBG_LAYER_LEVEL_WARNING");
Mark Lobodzinskia910dc82015-05-14 14:30:48 -0500169
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600170 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600171 this->app_info.pNext = NULL;
172 this->app_info.pAppName = "layer_tests";
173 this->app_info.appVersion = 1;
174 this->app_info.pEngineName = "unittest";
175 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600176 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600177
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600178 m_errorMonitor = new ErrorMonitor;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600179 InitFramework(instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
Tony Barbour30486ea2015-04-07 13:44:53 -0600180 }
181
182 virtual void TearDown() {
183 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600184 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600185 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600186 }
187};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500188
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600189VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600190{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600191 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600192
193 result = cmdBuffer.BeginCommandBuffer();
194
195 /*
196 * For render test all drawing happens in a single render pass
197 * on a single command buffer.
198 */
Chris Forbesfe133ef2015-06-16 14:05:59 +1200199 if (VK_SUCCESS == result && renderPass()) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600200 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
201 }
202
203 return result;
204}
205
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600206VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600207{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600208 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600209
Chris Forbesfe133ef2015-06-16 14:05:59 +1200210 if (renderPass()) {
211 cmdBuffer.EndRenderPass(renderPass());
212 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600213
214 result = cmdBuffer.EndCommandBuffer();
215
216 return result;
217}
218
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500219void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
220{
221 // Create identity matrix
222 int i;
223 struct vktriangle_vs_uniform data;
224
225 glm::mat4 Projection = glm::mat4(1.0f);
226 glm::mat4 View = glm::mat4(1.0f);
227 glm::mat4 Model = glm::mat4(1.0f);
228 glm::mat4 MVP = Projection * View * Model;
229 const int matrixSize = sizeof(MVP);
230 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
231
232 memcpy(&data.mvp, &MVP[0][0], matrixSize);
233
234 static const Vertex tri_data[] =
235 {
236 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
237 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
238 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
239 };
240
241 for (i=0; i<3; i++) {
242 data.position[i][0] = tri_data[i].posX;
243 data.position[i][1] = tri_data[i].posY;
244 data.position[i][2] = tri_data[i].posZ;
245 data.position[i][3] = tri_data[i].posW;
246 data.color[i][0] = tri_data[i].r;
247 data.color[i][1] = tri_data[i].g;
248 data.color[i][2] = tri_data[i].b;
249 data.color[i][3] = tri_data[i].a;
250 }
251
252 ASSERT_NO_FATAL_FAILURE(InitState());
253 ASSERT_NO_FATAL_FAILURE(InitViewport());
254
255 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
256
257 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
258 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
259
260 VkPipelineObj pipelineobj(m_device);
261 pipelineobj.AddShader(&vs);
262 pipelineobj.AddShader(&ps);
263
264 VkDescriptorSetObj descriptorSet(m_device);
265 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
266
267 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
268 VkCommandBufferObj cmdBuffer(m_device);
269 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
270
271 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
272
273 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
274
275 // render triangle
276 cmdBuffer.Draw(0, 3, 0, 1);
277
278 // finalize recording of the command buffer
279 EndCommandBuffer(cmdBuffer);
280
281 cmdBuffer.QueueCommandBuffer();
282}
283
284void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
285{
286 if (m_depthStencil->Initialized()) {
287 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
288 } else {
289 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
290 }
291
292 cmdBuffer->PrepareAttachments();
293 if ((failMask & BsoFailRaster) != BsoFailRaster) {
294 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
295 }
296 if ((failMask & BsoFailViewport) != BsoFailViewport) {
297 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
298 }
299 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
300 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
301 }
302 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
303 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
304 }
305 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
306 pipelineobj.CreateVKPipeline(descriptorSet);
307 cmdBuffer->BindPipeline(pipelineobj);
308 cmdBuffer->BindDescriptorSet(descriptorSet);
309}
310
311// ********************************************************************************************************************
312// ********************************************************************************************************************
313// ********************************************************************************************************************
314// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600315#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500316TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
317{
318 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600319 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500320 std::string msgString;
321
322 VkFenceCreateInfo fenceInfo = {};
323 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
324 fenceInfo.pNext = NULL;
325 fenceInfo.flags = 0;
326
327 ASSERT_NO_FATAL_FAILURE(InitState());
328 ASSERT_NO_FATAL_FAILURE(InitViewport());
329 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
330
331 VkCommandBufferObj cmdBuffer(m_device);
332 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
333
334 BeginCommandBuffer(cmdBuffer);
335 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
336 EndCommandBuffer(cmdBuffer);
337
338 testFence.init(*m_device, fenceInfo);
339
340 // Bypass framework since it does the waits automatically
341 VkResult err = VK_SUCCESS;
342 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
343 ASSERT_VK_SUCCESS( err );
344
345 m_errorMonitor->ClearState();
346 // Introduce failure by calling begin again before checking fence
347 vkResetCommandBuffer(cmdBuffer.obj());
348
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600349 msgFlags = m_errorMonitor->GetState(&msgString);
350 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
Mark Lobodzinski81078192015-05-19 10:28:29 -0500351 if (!strstr(msgString.c_str(),"Resetting CB")) {
352 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
353 }
354}
355
356TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
357{
358 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600359 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500360 std::string msgString;
361
362 VkFenceCreateInfo fenceInfo = {};
363 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
364 fenceInfo.pNext = NULL;
365 fenceInfo.flags = 0;
366
367 ASSERT_NO_FATAL_FAILURE(InitState());
368 ASSERT_NO_FATAL_FAILURE(InitViewport());
369 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
370
371 VkCommandBufferObj cmdBuffer(m_device);
372 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
373
374 BeginCommandBuffer(cmdBuffer);
375 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
376 EndCommandBuffer(cmdBuffer);
377
378 testFence.init(*m_device, fenceInfo);
379
380 // Bypass framework since it does the waits automatically
381 VkResult err = VK_SUCCESS;
382 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
383 ASSERT_VK_SUCCESS( err );
384
385 m_errorMonitor->ClearState();
386 // Introduce failure by calling begin again before checking fence
387 BeginCommandBuffer(cmdBuffer);
388
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600389 msgFlags = m_errorMonitor->GetState(&msgString);
390 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
Mark Lobodzinski81078192015-05-19 10:28:29 -0500391 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
392 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
393 }
394}
395
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500396TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
397{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600398 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500399 std::string msgString;
400 VkResult err;
401
402 ASSERT_NO_FATAL_FAILURE(InitState());
403 m_errorMonitor->ClearState();
404
405 // Create an image, allocate memory, free it, and then try to bind it
406 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500407 VkDeviceMemory mem;
408 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500409
410 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
411 const int32_t tex_width = 32;
412 const int32_t tex_height = 32;
413 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500414
415 const VkImageCreateInfo image_create_info = {
416 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
417 .pNext = NULL,
418 .imageType = VK_IMAGE_TYPE_2D,
419 .format = tex_format,
420 .extent = { tex_width, tex_height, 1 },
421 .mipLevels = 1,
422 .arraySize = 1,
423 .samples = 1,
424 .tiling = VK_IMAGE_TILING_LINEAR,
425 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
426 .flags = 0,
427 };
428 VkMemoryAllocInfo mem_alloc = {
429 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
430 .pNext = NULL,
431 .allocationSize = 0,
432 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
433 .memProps = 0,
434 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
435 };
436
437 err = vkCreateImage(m_device->device(), &image_create_info, &image);
438 ASSERT_VK_SUCCESS(err);
439
440 err = vkGetObjectInfo(m_device->device(),
441 VK_OBJECT_TYPE_IMAGE,
442 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500443 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
444 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500445 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500446 ASSERT_VK_SUCCESS(err);
447
Mark Lobodzinski23182612015-05-29 09:32:35 -0500448 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500449
450 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500451 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500452 ASSERT_VK_SUCCESS(err);
453
454 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500455 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500456 ASSERT_VK_SUCCESS(err);
457
458 // Map memory as if to initialize the image
459 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500460 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500461
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600462 msgFlags = m_errorMonitor->GetState(&msgString);
463 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to map memory not visible to CPU";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500464 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
465 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
466 }
467}
468
469TEST_F(VkLayerTest, BindInvalidMemory)
470{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600471 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500472 std::string msgString;
473 VkResult err;
474
475 ASSERT_NO_FATAL_FAILURE(InitState());
476 m_errorMonitor->ClearState();
477
478 // Create an image, allocate memory, free it, and then try to bind it
479 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500480 VkDeviceMemory mem;
481 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500482
483 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
484 const int32_t tex_width = 32;
485 const int32_t tex_height = 32;
486 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500487
488 const VkImageCreateInfo image_create_info = {
489 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
490 .pNext = NULL,
491 .imageType = VK_IMAGE_TYPE_2D,
492 .format = tex_format,
493 .extent = { tex_width, tex_height, 1 },
494 .mipLevels = 1,
495 .arraySize = 1,
496 .samples = 1,
497 .tiling = VK_IMAGE_TILING_LINEAR,
498 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
499 .flags = 0,
500 };
501 VkMemoryAllocInfo mem_alloc = {
502 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
503 .pNext = NULL,
504 .allocationSize = 0,
505 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
506 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
507 };
508
509 err = vkCreateImage(m_device->device(), &image_create_info, &image);
510 ASSERT_VK_SUCCESS(err);
511
512 err = vkGetObjectInfo(m_device->device(),
513 VK_OBJECT_TYPE_IMAGE,
514 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500515 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
516 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500517 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500518 ASSERT_VK_SUCCESS(err);
519
Mark Lobodzinski23182612015-05-29 09:32:35 -0500520 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500521
522 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500523 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500524 ASSERT_VK_SUCCESS(err);
525
526 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500527 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500528 ASSERT_VK_SUCCESS(err);
529
530 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500531 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500532 ASSERT_VK_SUCCESS(err);
533
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600534 msgFlags = m_errorMonitor->GetState(&msgString);
535 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to bind a freed memory object";
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500536 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500537 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
538 }
539}
540
541TEST_F(VkLayerTest, FreeBoundMemory)
542{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600543 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500544 std::string msgString;
545 VkResult err;
546
547 ASSERT_NO_FATAL_FAILURE(InitState());
548 m_errorMonitor->ClearState();
549
550 // Create an image, allocate memory, free it, and then try to bind it
551 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500552 VkDeviceMemory mem;
553 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500554
555 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
556 const int32_t tex_width = 32;
557 const int32_t tex_height = 32;
558 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500559
560 const VkImageCreateInfo image_create_info = {
561 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
562 .pNext = NULL,
563 .imageType = VK_IMAGE_TYPE_2D,
564 .format = tex_format,
565 .extent = { tex_width, tex_height, 1 },
566 .mipLevels = 1,
567 .arraySize = 1,
568 .samples = 1,
569 .tiling = VK_IMAGE_TILING_LINEAR,
570 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
571 .flags = 0,
572 };
573 VkMemoryAllocInfo mem_alloc = {
574 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
575 .pNext = NULL,
576 .allocationSize = 0,
577 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
578 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
579 };
580
581 err = vkCreateImage(m_device->device(), &image_create_info, &image);
582 ASSERT_VK_SUCCESS(err);
583
584 err = vkGetObjectInfo(m_device->device(),
585 VK_OBJECT_TYPE_IMAGE,
586 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500587 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
588 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500589 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500590 ASSERT_VK_SUCCESS(err);
591
Mark Lobodzinski23182612015-05-29 09:32:35 -0500592 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500593
594 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500595 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500596 ASSERT_VK_SUCCESS(err);
597
598 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500599 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500600 ASSERT_VK_SUCCESS(err);
601
602 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500603 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500604 ASSERT_VK_SUCCESS(err);
605
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600606 msgFlags = m_errorMonitor->GetState(&msgString);
607 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT) << "Did not receive an warning while tring to free bound memory";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500608 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
609 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
610 }
611}
612
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500613TEST_F(VkLayerTest, RebindMemory)
614{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600615 VkFlags msgFlags;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500616 std::string msgString;
617 VkResult err;
618
619 ASSERT_NO_FATAL_FAILURE(InitState());
620 m_errorMonitor->ClearState();
621
622 // Create an image, allocate memory, free it, and then try to bind it
623 VkImage image;
624 VkDeviceMemory mem1;
625 VkDeviceMemory mem2;
626 VkMemoryRequirements mem_reqs;
627
628 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
629 const int32_t tex_width = 32;
630 const int32_t tex_height = 32;
631 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
632
633 const VkImageCreateInfo image_create_info = {
634 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
635 .pNext = NULL,
636 .imageType = VK_IMAGE_TYPE_2D,
637 .format = tex_format,
638 .extent = { tex_width, tex_height, 1 },
639 .mipLevels = 1,
640 .arraySize = 1,
641 .samples = 1,
642 .tiling = VK_IMAGE_TILING_LINEAR,
643 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
644 .flags = 0,
645 };
646 VkMemoryAllocInfo mem_alloc = {
647 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
648 .pNext = NULL,
649 .allocationSize = 0,
650 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
651 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
652 };
653
654 err = vkCreateImage(m_device->device(), &image_create_info, &image);
655 ASSERT_VK_SUCCESS(err);
656
657 err = vkGetObjectInfo(m_device->device(),
658 VK_OBJECT_TYPE_IMAGE,
659 image,
660 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
661 &mem_reqs_size,
662 &mem_reqs);
663 ASSERT_VK_SUCCESS(err);
664
665 mem_alloc.allocationSize = mem_reqs.size;
666
667 // allocate 2 memory objects
668 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
669 ASSERT_VK_SUCCESS(err);
670 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
671 ASSERT_VK_SUCCESS(err);
672
673 // Bind first memory object to Image object
674 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
675 ASSERT_VK_SUCCESS(err);
676
677 // Introduce validation failure, try to bind a different memory object to the same image object
678 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
679 ASSERT_VK_SUCCESS(err);
680
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600681 msgFlags = m_errorMonitor->GetState(&msgString);
682 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to rebind an object";
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500683 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
684 FAIL() << "Error received did not match expected message when rebinding memory to an object";
685 }
686}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500687
688TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
689{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600690 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500691 std::string msgString;
692 VkResult err;
693
694 ASSERT_NO_FATAL_FAILURE(InitState());
695 m_errorMonitor->ClearState();
696
697 // Create an image object, allocate memory, destroy the object and then try to bind it
698 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500699 VkDeviceMemory mem;
700 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500701
702 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
703 const int32_t tex_width = 32;
704 const int32_t tex_height = 32;
705 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500706
707 const VkImageCreateInfo image_create_info = {
708 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
709 .pNext = NULL,
710 .imageType = VK_IMAGE_TYPE_2D,
711 .format = tex_format,
712 .extent = { tex_width, tex_height, 1 },
713 .mipLevels = 1,
714 .arraySize = 1,
715 .samples = 1,
716 .tiling = VK_IMAGE_TILING_LINEAR,
717 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
718 .flags = 0,
719 };
720 VkMemoryAllocInfo mem_alloc = {
721 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
722 .pNext = NULL,
723 .allocationSize = 0,
724 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
725 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
726 };
727
728 err = vkCreateImage(m_device->device(), &image_create_info, &image);
729 ASSERT_VK_SUCCESS(err);
730
731 err = vkGetObjectInfo(m_device->device(),
732 VK_OBJECT_TYPE_IMAGE,
733 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500734 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
735 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500736 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500737 ASSERT_VK_SUCCESS(err);
738
Mark Lobodzinski23182612015-05-29 09:32:35 -0500739 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500740
741 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500742 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500743 ASSERT_VK_SUCCESS(err);
744
745 // Introduce validation failure, destroy Image object before binding
746 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
747 ASSERT_VK_SUCCESS(err);
748
749 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500750 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500751 ASSERT_VK_SUCCESS(err);
752
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600753 msgFlags = m_errorMonitor->GetState(&msgString);
754 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while binding memory to a destroyed object";
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500755 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500756 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
757 }
758}
759
Tony Barbour8508b8e2015-04-09 10:48:04 -0600760TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600761{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600762 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600763 VkFlags msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -0600764 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600765
766 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600767 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
768 fenceInfo.pNext = NULL;
769 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600770
Tony Barbour30486ea2015-04-07 13:44:53 -0600771 ASSERT_NO_FATAL_FAILURE(InitState());
772 ASSERT_NO_FATAL_FAILURE(InitViewport());
773 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
774
Tony Barbour01999182015-04-09 12:58:51 -0600775 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600776 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
777
Tony Barbour8508b8e2015-04-09 10:48:04 -0600778 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600779 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600780 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600781
782 testFence.init(*m_device, fenceInfo);
783 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600784 cmdBuffer.QueueCommandBuffer(testFence.obj());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600785 msgFlags = m_errorMonitor->GetState(&msgString);
786 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600787 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500788 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600789 }
790
791}
792
793TEST_F(VkLayerTest, ResetUnsignaledFence)
794{
795 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600796 VkFlags msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600797 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600798 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600799 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
800 fenceInfo.pNext = NULL;
801
Tony Barbour8508b8e2015-04-09 10:48:04 -0600802 ASSERT_NO_FATAL_FAILURE(InitState());
803 testFence.init(*m_device, fenceInfo);
804 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600805 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600806 vkResetFences(m_device->device(), 1, fences);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600807 msgFlags = m_errorMonitor->GetState(&msgString);
808 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from submitting fence with UNSIGNALED state to vkResetFences";
Tony Barbour01999182015-04-09 12:58:51 -0600809 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500810 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600811 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600812
813}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600814#endif
815#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600816
Tony Barbourdb686622015-05-06 09:35:56 -0600817TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
818{
819 VkEventCreateInfo event_info;
820 VkEvent event;
821 VkMemoryRequirements mem_req;
822 size_t data_size = sizeof(mem_req);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600823 VkFlags msgFlags;
Tony Barbourdb686622015-05-06 09:35:56 -0600824 std::string msgString;
825 VkResult err;
826
827 ASSERT_NO_FATAL_FAILURE(InitState());
828 memset(&event_info, 0, sizeof(event_info));
829 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
830
831 err = vkCreateEvent(device(), &event_info, &event);
832 ASSERT_VK_SUCCESS(err);
833 m_errorMonitor->ClearState();
834 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
835 &data_size, &mem_req);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600836 msgFlags = m_errorMonitor->GetState(&msgString);
837 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from mismatched types in vkGetObjectInfo";
Tony Barbourdb686622015-05-06 09:35:56 -0600838 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500839 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600840 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500841}
Tony Barbourdb686622015-05-06 09:35:56 -0600842
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500843TEST_F(VkLayerTest, RasterStateNotBound)
844{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600845 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500846 std::string msgString;
847
848 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
849
850 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
851
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600852 msgFlags = m_errorMonitor->GetState(&msgString);
853 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500854 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
855 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
856 }
857}
858
859TEST_F(VkLayerTest, ViewportStateNotBound)
860{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600861 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500862 std::string msgString;
863 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
864
865 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
866
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600867 msgFlags = m_errorMonitor->GetState(&msgString);
868 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500869 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
870 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
871 }
872}
873
874TEST_F(VkLayerTest, ColorBlendStateNotBound)
875{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600876 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500877 std::string msgString;
878
879 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
880
881 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
882
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600883 msgFlags = m_errorMonitor->GetState(&msgString);
884 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500885 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
886 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
887 }
888}
889
890TEST_F(VkLayerTest, DepthStencilStateNotBound)
891{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600892 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500893 std::string msgString;
894
895 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
896
897 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
898
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600899 msgFlags = m_errorMonitor->GetState(&msgString);
900 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500901 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
902 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
903 }
Tony Barbourdb686622015-05-06 09:35:56 -0600904}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600905#endif
906#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600907TEST_F(VkLayerTest, PipelineNotBound)
908{
909 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600910 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600911 std::string msgString;
912
913 ASSERT_NO_FATAL_FAILURE(InitState());
914 m_errorMonitor->ClearState();
915 VkCommandBufferObj cmdBuffer(m_device);
916 BeginCommandBuffer(cmdBuffer);
917 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
918 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600919 msgFlags = m_errorMonitor->GetState(&msgString);
920 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600921 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
922 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
923 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600924}
925
926TEST_F(VkLayerTest, InvalidDescriptorPool)
927{
928 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
929 // The DS check for this is after driver has been called to validate DS internal data struct
930 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600931/* VkFlags msgFlags;
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600932 std::string msgString;
933 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
934 vkResetDescriptorPool(device(), badPool);
935
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600936 msgFlags = m_errorMonitor->GetState(&msgString);
937 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600938 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
939 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
940 }*/
941}
942
943TEST_F(VkLayerTest, InvalidDescriptorSet)
944{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600945 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
946 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600947 // Create a valid cmd buffer
948 // call vkCmdBindDescriptorSets w/ false DS
949}
950
951TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
952{
953 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
954 // The DS check for this is after driver has been called to validate DS internal data struct
955}
956
957TEST_F(VkLayerTest, InvalidPipeline)
958{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600959 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
960 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600961 // Create a valid cmd buffer
962 // call vkCmdBindPipeline w/ false Pipeline
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600963 VkFlags msgFlags;
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600964 std::string msgString;
965
966 ASSERT_NO_FATAL_FAILURE(InitState());
967 m_errorMonitor->ClearState();
968 VkCommandBufferObj cmdBuffer(m_device);
969 BeginCommandBuffer(cmdBuffer);
970 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
971 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600972 msgFlags = m_errorMonitor->GetState(&msgString);
973 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600974 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
975 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
976 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600977}
978
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600979TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600980{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600981 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600982 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600983 std::string msgString;
984 VkResult err;
985
986 ASSERT_NO_FATAL_FAILURE(InitState());
987 m_errorMonitor->ClearState();
988 VkCommandBufferObj cmdBuffer(m_device);
989 const VkDescriptorTypeCount ds_type_count = {
990 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
991 .count = 1,
992 };
993 const VkDescriptorPoolCreateInfo ds_pool_ci = {
994 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
995 .pNext = NULL,
996 .count = 1,
997 .pTypeCount = &ds_type_count,
998 };
999 VkDescriptorPool ds_pool;
1000 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1001 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001002
1003 const VkDescriptorSetLayoutBinding dsl_binding = {
1004 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001005 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001006 .stageFlags = VK_SHADER_STAGE_ALL,
1007 .pImmutableSamplers = NULL,
1008 };
1009
1010 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1011 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1012 .pNext = NULL,
1013 .count = 1,
1014 .pBinding = &dsl_binding,
1015 };
1016 VkDescriptorSetLayout ds_layout;
1017 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1018 ASSERT_VK_SUCCESS(err);
1019
1020 VkDescriptorSet descriptorSet;
1021 uint32_t ds_count = 0;
1022 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1023 ASSERT_VK_SUCCESS(err);
1024
1025 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1026 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1027 .pNext = NULL,
1028 .descriptorSetCount = 1,
1029 .pSetLayouts = &ds_layout,
1030 };
1031
1032 VkPipelineLayout pipeline_layout;
1033 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1034 ASSERT_VK_SUCCESS(err);
1035
1036 size_t shader_len = strlen(bindStateVertShaderText);
1037 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1038 void* pCode = malloc(codeSize);
1039
1040 /* try version 0 first: VkShaderStage followed by GLSL */
1041 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1042 ((uint32_t *) pCode)[1] = 0;
1043 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1044 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1045
1046 const VkShaderCreateInfo vs_ci = {
1047 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1048 .pNext = NULL,
1049 .codeSize = codeSize,
1050 .pCode = pCode,
1051 .flags = 0,
1052 };
1053 VkShader vs;
1054 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1055 ASSERT_VK_SUCCESS(err);
1056
1057 const VkPipelineShader vs_pipe_shader = {
1058 .stage = VK_SHADER_STAGE_VERTEX,
1059 .shader = vs,
1060 .linkConstBufferCount = 0,
1061 .pLinkConstBufferInfo = NULL,
1062 .pSpecializationInfo = NULL,
1063 };
1064 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1065 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1066 .pNext = NULL,
1067 .shader = vs_pipe_shader,
1068 };
1069 const VkGraphicsPipelineCreateInfo gp_ci = {
1070 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1071 .pNext = &pipe_vs_ci,
1072 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1073 .layout = pipeline_layout,
1074 };
1075
1076 VkPipeline pipeline;
1077 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1078 ASSERT_VK_SUCCESS(err);
1079
1080 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1081 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1082
1083 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1084 m_device->get_device_queue();
1085 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1086
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001087 msgFlags = m_errorMonitor->GetState(&msgString);
1088 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001089 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1090 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1091 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001092}
1093
1094TEST_F(VkLayerTest, InvalidDynamicStateObject)
1095{
1096 // Create a valid cmd buffer
1097 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001098 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1099 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001100}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001101
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001102TEST_F(VkLayerTest, VtxBufferBadIndex)
1103{
1104 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001105 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001106 std::string msgString;
1107 VkResult err;
1108
1109 ASSERT_NO_FATAL_FAILURE(InitState());
1110 m_errorMonitor->ClearState();
1111 VkCommandBufferObj cmdBuffer(m_device);
1112 const VkDescriptorTypeCount ds_type_count = {
1113 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1114 .count = 1,
1115 };
1116 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1117 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1118 .pNext = NULL,
1119 .count = 1,
1120 .pTypeCount = &ds_type_count,
1121 };
1122 VkDescriptorPool ds_pool;
1123 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1124 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001125
1126 const VkDescriptorSetLayoutBinding dsl_binding = {
1127 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001128 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001129 .stageFlags = VK_SHADER_STAGE_ALL,
1130 .pImmutableSamplers = NULL,
1131 };
1132
1133 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1134 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1135 .pNext = NULL,
1136 .count = 1,
1137 .pBinding = &dsl_binding,
1138 };
1139 VkDescriptorSetLayout ds_layout;
1140 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1141 ASSERT_VK_SUCCESS(err);
1142
1143 VkDescriptorSet descriptorSet;
1144 uint32_t ds_count = 0;
1145 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1146 ASSERT_VK_SUCCESS(err);
1147
1148 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1149 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1150 .pNext = NULL,
1151 .descriptorSetCount = 1,
1152 .pSetLayouts = &ds_layout,
1153 };
1154
1155 VkPipelineLayout pipeline_layout;
1156 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1157 ASSERT_VK_SUCCESS(err);
1158
1159 size_t shader_len = strlen(bindStateVertShaderText);
1160 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1161 void* pCode = malloc(codeSize);
1162
1163 /* try version 0 first: VkShaderStage followed by GLSL */
1164 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1165 ((uint32_t *) pCode)[1] = 0;
1166 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1167 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1168
1169 const VkShaderCreateInfo vs_ci = {
1170 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1171 .pNext = NULL,
1172 .codeSize = codeSize,
1173 .pCode = pCode,
1174 .flags = 0,
1175 };
1176 VkShader vs;
1177 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1178
1179 const VkPipelineShader vs_pipe_shader = {
1180 .stage = VK_SHADER_STAGE_VERTEX,
1181 .shader = vs,
1182 .linkConstBufferCount = 0,
1183 .pLinkConstBufferInfo = NULL,
1184 .pSpecializationInfo = NULL,
1185 };
1186 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1187 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1188 .pNext = NULL,
1189 .shader = vs_pipe_shader,
1190 };
1191 const VkGraphicsPipelineCreateInfo gp_ci = {
1192 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1193 .pNext = &pipe_vs_ci,
1194 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1195 .layout = pipeline_layout,
1196 };
1197
1198 VkPipeline pipeline;
1199 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1200 ASSERT_VK_SUCCESS(err);
1201
1202 err= cmdBuffer.BeginCommandBuffer();
1203 ASSERT_VK_SUCCESS(err);
1204 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1205 // Should error before calling to driver so don't care about actual data
1206 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1207
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001208 msgFlags = m_errorMonitor->GetState(&msgString);
1209 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001210 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1211 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1212 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001213}
1214
1215TEST_F(VkLayerTest, DSTypeMismatch)
1216{
1217 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001218 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001219 std::string msgString;
1220 VkResult err;
1221
1222 ASSERT_NO_FATAL_FAILURE(InitState());
1223 m_errorMonitor->ClearState();
1224 //VkDescriptorSetObj descriptorSet(m_device);
1225 const VkDescriptorTypeCount ds_type_count = {
1226 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1227 .count = 1,
1228 };
1229 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1230 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1231 .pNext = NULL,
1232 .count = 1,
1233 .pTypeCount = &ds_type_count,
1234 };
1235 VkDescriptorPool ds_pool;
1236 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1237 ASSERT_VK_SUCCESS(err);
1238 const VkDescriptorSetLayoutBinding dsl_binding = {
1239 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001240 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001241 .stageFlags = VK_SHADER_STAGE_ALL,
1242 .pImmutableSamplers = NULL,
1243 };
1244
1245 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1246 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1247 .pNext = NULL,
1248 .count = 1,
1249 .pBinding = &dsl_binding,
1250 };
1251 VkDescriptorSetLayout ds_layout;
1252 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1253 ASSERT_VK_SUCCESS(err);
1254
1255 VkDescriptorSet descriptorSet;
1256 uint32_t ds_count = 0;
1257 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1258 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001259
1260 const VkSamplerCreateInfo sampler_ci = {
1261 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1262 .pNext = NULL,
1263 .magFilter = VK_TEX_FILTER_NEAREST,
1264 .minFilter = VK_TEX_FILTER_NEAREST,
1265 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1266 .addressU = VK_TEX_ADDRESS_CLAMP,
1267 .addressV = VK_TEX_ADDRESS_CLAMP,
1268 .addressW = VK_TEX_ADDRESS_CLAMP,
1269 .mipLodBias = 1.0,
1270 .maxAnisotropy = 1,
1271 .compareOp = VK_COMPARE_OP_NEVER,
1272 .minLod = 1.0,
1273 .maxLod = 1.0,
1274 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1275 };
1276 VkSampler sampler;
1277 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1278 ASSERT_VK_SUCCESS(err);
1279
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001280 VkDescriptorInfo descriptor_info;
1281 memset(&descriptor_info, 0, sizeof(descriptor_info));
1282 descriptor_info.sampler = sampler;
1283
1284 VkWriteDescriptorSet descriptor_write;
1285 memset(&descriptor_write, 0, sizeof(descriptor_write));
1286 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1287 descriptor_write.destSet = descriptorSet;
1288 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001289 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001290 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1291 descriptor_write.pDescriptors = &descriptor_info;
1292
1293 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1294
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001295 msgFlags = m_errorMonitor->GetState(&msgString);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001296 std::cout << msgString << "\n";
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001297 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating BUFFER Descriptor w/ incorrect type of SAMPLER.";
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001298 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1299 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 -06001300 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001301}
1302
1303TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1304{
1305 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001306 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001307 std::string msgString;
1308 VkResult err;
1309
1310 ASSERT_NO_FATAL_FAILURE(InitState());
1311 m_errorMonitor->ClearState();
1312 //VkDescriptorSetObj descriptorSet(m_device);
1313 const VkDescriptorTypeCount ds_type_count = {
1314 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1315 .count = 1,
1316 };
1317 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1318 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1319 .pNext = NULL,
1320 .count = 1,
1321 .pTypeCount = &ds_type_count,
1322 };
1323 VkDescriptorPool ds_pool;
1324 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1325 ASSERT_VK_SUCCESS(err);
1326 const VkDescriptorSetLayoutBinding dsl_binding = {
1327 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001328 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001329 .stageFlags = VK_SHADER_STAGE_ALL,
1330 .pImmutableSamplers = NULL,
1331 };
1332
1333 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1334 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1335 .pNext = NULL,
1336 .count = 1,
1337 .pBinding = &dsl_binding,
1338 };
1339 VkDescriptorSetLayout ds_layout;
1340 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1341 ASSERT_VK_SUCCESS(err);
1342
1343 VkDescriptorSet descriptorSet;
1344 uint32_t ds_count = 0;
1345 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1346 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001347
1348 const VkSamplerCreateInfo sampler_ci = {
1349 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1350 .pNext = NULL,
1351 .magFilter = VK_TEX_FILTER_NEAREST,
1352 .minFilter = VK_TEX_FILTER_NEAREST,
1353 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1354 .addressU = VK_TEX_ADDRESS_CLAMP,
1355 .addressV = VK_TEX_ADDRESS_CLAMP,
1356 .addressW = VK_TEX_ADDRESS_CLAMP,
1357 .mipLodBias = 1.0,
1358 .maxAnisotropy = 1,
1359 .compareOp = VK_COMPARE_OP_NEVER,
1360 .minLod = 1.0,
1361 .maxLod = 1.0,
1362 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1363 };
1364 VkSampler sampler;
1365 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1366 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001367
1368 VkDescriptorInfo descriptor_info;
1369 memset(&descriptor_info, 0, sizeof(descriptor_info));
1370 descriptor_info.sampler = sampler;
1371
1372 VkWriteDescriptorSet descriptor_write;
1373 memset(&descriptor_write, 0, sizeof(descriptor_write));
1374 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1375 descriptor_write.destSet = descriptorSet;
1376 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1377 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001378 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001379 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1380 descriptor_write.pDescriptors = &descriptor_info;
1381
1382 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1383
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001384 msgFlags = m_errorMonitor->GetState(&msgString);
1385 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ index out of bounds.";
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001386 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1387 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 -06001388 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001389}
1390
1391TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1392{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001393 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001394 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001395 std::string msgString;
1396 VkResult err;
1397
1398 ASSERT_NO_FATAL_FAILURE(InitState());
1399 m_errorMonitor->ClearState();
1400 //VkDescriptorSetObj descriptorSet(m_device);
1401 const VkDescriptorTypeCount ds_type_count = {
1402 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1403 .count = 1,
1404 };
1405 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1406 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1407 .pNext = NULL,
1408 .count = 1,
1409 .pTypeCount = &ds_type_count,
1410 };
1411 VkDescriptorPool ds_pool;
1412 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1413 ASSERT_VK_SUCCESS(err);
1414 const VkDescriptorSetLayoutBinding dsl_binding = {
1415 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001416 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001417 .stageFlags = VK_SHADER_STAGE_ALL,
1418 .pImmutableSamplers = NULL,
1419 };
1420
1421 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1422 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1423 .pNext = NULL,
1424 .count = 1,
1425 .pBinding = &dsl_binding,
1426 };
1427 VkDescriptorSetLayout ds_layout;
1428 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1429 ASSERT_VK_SUCCESS(err);
1430
1431 VkDescriptorSet descriptorSet;
1432 uint32_t ds_count = 0;
1433 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1434 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001435
1436 const VkSamplerCreateInfo sampler_ci = {
1437 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1438 .pNext = NULL,
1439 .magFilter = VK_TEX_FILTER_NEAREST,
1440 .minFilter = VK_TEX_FILTER_NEAREST,
1441 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1442 .addressU = VK_TEX_ADDRESS_CLAMP,
1443 .addressV = VK_TEX_ADDRESS_CLAMP,
1444 .addressW = VK_TEX_ADDRESS_CLAMP,
1445 .mipLodBias = 1.0,
1446 .maxAnisotropy = 1,
1447 .compareOp = VK_COMPARE_OP_NEVER,
1448 .minLod = 1.0,
1449 .maxLod = 1.0,
1450 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1451 };
1452 VkSampler sampler;
1453 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1454 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001455
1456 VkDescriptorInfo descriptor_info;
1457 memset(&descriptor_info, 0, sizeof(descriptor_info));
1458 descriptor_info.sampler = sampler;
1459
1460 VkWriteDescriptorSet descriptor_write;
1461 memset(&descriptor_write, 0, sizeof(descriptor_write));
1462 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1463 descriptor_write.destSet = descriptorSet;
1464 descriptor_write.destBinding = 2;
1465 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001466 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001467 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1468 descriptor_write.pDescriptors = &descriptor_info;
1469
1470 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1471
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001472 msgFlags = m_errorMonitor->GetState(&msgString);
1473 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ count too large for layout.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001474 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1475 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1476 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001477}
1478
1479TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1480{
1481 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001482 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001483 std::string msgString;
1484 VkResult err;
1485
1486 ASSERT_NO_FATAL_FAILURE(InitState());
1487 m_errorMonitor->ClearState();
1488 //VkDescriptorSetObj descriptorSet(m_device);
1489 const VkDescriptorTypeCount ds_type_count = {
1490 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1491 .count = 1,
1492 };
1493 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1494 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1495 .pNext = NULL,
1496 .count = 1,
1497 .pTypeCount = &ds_type_count,
1498 };
1499 VkDescriptorPool ds_pool;
1500 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1501 ASSERT_VK_SUCCESS(err);
1502 const VkDescriptorSetLayoutBinding dsl_binding = {
1503 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001504 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001505 .stageFlags = VK_SHADER_STAGE_ALL,
1506 .pImmutableSamplers = NULL,
1507 };
1508
1509 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1510 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1511 .pNext = NULL,
1512 .count = 1,
1513 .pBinding = &dsl_binding,
1514 };
1515 VkDescriptorSetLayout ds_layout;
1516 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1517 ASSERT_VK_SUCCESS(err);
1518
1519 VkDescriptorSet descriptorSet;
1520 uint32_t ds_count = 0;
1521 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1522 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001523
1524 const VkSamplerCreateInfo sampler_ci = {
1525 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1526 .pNext = NULL,
1527 .magFilter = VK_TEX_FILTER_NEAREST,
1528 .minFilter = VK_TEX_FILTER_NEAREST,
1529 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1530 .addressU = VK_TEX_ADDRESS_CLAMP,
1531 .addressV = VK_TEX_ADDRESS_CLAMP,
1532 .addressW = VK_TEX_ADDRESS_CLAMP,
1533 .mipLodBias = 1.0,
1534 .maxAnisotropy = 1,
1535 .compareOp = VK_COMPARE_OP_NEVER,
1536 .minLod = 1.0,
1537 .maxLod = 1.0,
1538 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1539 };
1540 VkSampler sampler;
1541 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1542 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001543
1544
1545 VkDescriptorInfo descriptor_info;
1546 memset(&descriptor_info, 0, sizeof(descriptor_info));
1547 descriptor_info.sampler = sampler;
1548
1549 VkWriteDescriptorSet descriptor_write;
1550 memset(&descriptor_write, 0, sizeof(descriptor_write));
1551 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1552 descriptor_write.destSet = descriptorSet;
1553 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001554 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001555 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1556 descriptor_write.pDescriptors = &descriptor_info;
1557
1558 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1559
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001560 msgFlags = m_errorMonitor->GetState(&msgString);
1561 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ invalid struct type.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001562 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1563 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1564 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001565}
1566
1567TEST_F(VkLayerTest, NumSamplesMismatch)
1568{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001569 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001570 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001571 std::string msgString;
1572 VkResult err;
1573
1574 ASSERT_NO_FATAL_FAILURE(InitState());
1575 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1576 m_errorMonitor->ClearState();
1577 VkCommandBufferObj cmdBuffer(m_device);
1578 const VkDescriptorTypeCount ds_type_count = {
1579 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1580 .count = 1,
1581 };
1582 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1583 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1584 .pNext = NULL,
1585 .count = 1,
1586 .pTypeCount = &ds_type_count,
1587 };
1588 VkDescriptorPool ds_pool;
1589 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1590 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001591
1592 const VkDescriptorSetLayoutBinding dsl_binding = {
1593 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001594 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001595 .stageFlags = VK_SHADER_STAGE_ALL,
1596 .pImmutableSamplers = NULL,
1597 };
1598
1599 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1600 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1601 .pNext = NULL,
1602 .count = 1,
1603 .pBinding = &dsl_binding,
1604 };
1605 VkDescriptorSetLayout ds_layout;
1606 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1607 ASSERT_VK_SUCCESS(err);
1608
1609 VkDescriptorSet descriptorSet;
1610 uint32_t ds_count = 0;
1611 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1612 ASSERT_VK_SUCCESS(err);
1613
1614 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1615 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1616 .pNext = NULL,
Tony Barbourd1e95582015-06-03 12:30:49 -06001617 .samples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001618 .multisampleEnable = 1,
1619 .sampleShadingEnable = 0,
1620 .minSampleShading = 1.0,
1621 .sampleMask = 15,
1622 };
1623
1624 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1625 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1626 .pNext = NULL,
1627 .descriptorSetCount = 1,
1628 .pSetLayouts = &ds_layout,
1629 };
1630
1631 VkPipelineLayout pipeline_layout;
1632 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1633 ASSERT_VK_SUCCESS(err);
1634
1635 size_t shader_len = strlen(bindStateVertShaderText);
1636 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1637 void* pCode = malloc(codeSize);
1638
1639 /* try version 0 first: VkShaderStage followed by GLSL */
1640 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1641 ((uint32_t *) pCode)[1] = 0;
1642 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1643 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1644
1645 const VkShaderCreateInfo vs_ci = {
1646 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1647 .pNext = NULL,
1648 .codeSize = codeSize,
1649 .pCode = pCode,
1650 .flags = 0,
1651 };
1652 VkShader vs;
1653 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1654 ASSERT_VK_SUCCESS(err);
1655
1656 const VkPipelineShader vs_pipe_shader = {
1657 .stage = VK_SHADER_STAGE_VERTEX,
1658 .shader = vs,
1659 .linkConstBufferCount = 0,
1660 .pLinkConstBufferInfo = NULL,
1661 .pSpecializationInfo = NULL,
1662 };
1663 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1664 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1665 .pNext = &pipe_ms_state_ci,
1666 .shader = vs_pipe_shader,
1667 };
1668 const VkGraphicsPipelineCreateInfo gp_ci = {
1669 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1670 .pNext = &pipe_vs_ci,
1671 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1672 .layout = pipeline_layout,
1673 };
1674
1675 VkPipeline pipeline;
1676 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1677 ASSERT_VK_SUCCESS(err);
1678
1679 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1680 BeginCommandBuffer(cmdBuffer);
1681 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1682
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001683 msgFlags = m_errorMonitor->GetState(&msgString);
1684 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001685 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1686 FAIL() << "Error received was not 'Num samples mismatch!...'";
1687 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001688}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001689#endif
1690#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001691#if GTEST_IS_THREADSAFE
1692struct thread_data_struct {
1693 VkCmdBuffer cmdBuffer;
1694 VkEvent event;
1695 bool bailout;
1696};
1697
1698extern "C" void *AddToCommandBuffer(void *arg)
1699{
1700 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1701 std::string msgString;
1702
1703 for (int i = 0; i<10000; i++) {
1704 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1705 if (data->bailout) {
1706 break;
1707 }
1708 }
1709 return NULL;
1710}
1711
1712TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1713{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001714 VkFlags msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -06001715 std::string msgString;
1716 pthread_t thread;
1717 pthread_attr_t thread_attr;
1718
1719 ASSERT_NO_FATAL_FAILURE(InitState());
1720 ASSERT_NO_FATAL_FAILURE(InitViewport());
1721 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1722
1723 VkCommandBufferObj cmdBuffer(m_device);
1724
1725 m_errorMonitor->ClearState();
1726 pthread_attr_init(&thread_attr);
1727 BeginCommandBuffer(cmdBuffer);
1728
1729 VkEventCreateInfo event_info;
1730 VkEvent event;
1731 VkMemoryRequirements mem_req;
1732 size_t data_size = sizeof(mem_req);
1733 VkResult err;
1734
1735 memset(&event_info, 0, sizeof(event_info));
1736 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1737
1738 err = vkCreateEvent(device(), &event_info, &event);
1739 ASSERT_VK_SUCCESS(err);
1740
1741 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1742 &data_size, &mem_req);
1743 ASSERT_VK_SUCCESS(err);
1744
1745 VkMemoryAllocInfo mem_info;
1746 VkDeviceMemory event_mem;
1747
1748 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1749
1750 memset(&mem_info, 0, sizeof(mem_info));
1751 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1752 mem_info.allocationSize = mem_req.size;
1753 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1754 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1755 err = vkAllocMemory(device(), &mem_info, &event_mem);
1756 ASSERT_VK_SUCCESS(err);
1757
Mark Lobodzinski23182612015-05-29 09:32:35 -05001758 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001759 ASSERT_VK_SUCCESS(err);
1760
1761 err = vkResetEvent(device(), event);
1762 ASSERT_VK_SUCCESS(err);
1763
1764 struct thread_data_struct data;
1765 data.cmdBuffer = cmdBuffer.obj();
1766 data.event = event;
1767 data.bailout = false;
1768 m_errorMonitor->SetBailout(&data.bailout);
1769 // Add many entries to command buffer from another thread.
1770 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1771 // Add many entries to command buffer from this thread at the same time.
1772 AddToCommandBuffer(&data);
1773 pthread_join(thread, NULL);
1774 EndCommandBuffer(cmdBuffer);
1775
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001776 msgFlags = m_errorMonitor->GetState(&msgString);
1777 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_INFO_BIT) << "Did not receive an err from using one VkCommandBufferObj in two threads";
Mike Stroyan09aae812015-05-12 16:00:45 -06001778 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001779 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001780 }
1781
1782}
1783#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001784#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12001785
1786#if SHADER_CHECKER_TESTS
1787TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
1788{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001789 VkFlags msgFlags;
Chris Forbes5af3bf22015-05-25 11:13:08 +12001790 std::string msgString;
1791 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001792 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001793
1794 char const *vsSource =
1795 "#version 140\n"
1796 "#extension GL_ARB_separate_shader_objects: require\n"
1797 "#extension GL_ARB_shading_language_420pack: require\n"
1798 "\n"
1799 "layout(location=0) out float x;\n"
1800 "void main(){\n"
1801 " gl_Position = vec4(1);\n"
1802 " x = 0;\n"
1803 "}\n";
1804 char const *fsSource =
1805 "#version 140\n"
1806 "#extension GL_ARB_separate_shader_objects: require\n"
1807 "#extension GL_ARB_shading_language_420pack: require\n"
1808 "\n"
1809 "layout(location=0) out vec4 color;\n"
1810 "void main(){\n"
1811 " color = vec4(1);\n"
1812 "}\n";
1813
1814 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1815 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1816
1817 VkPipelineObj pipe(m_device);
1818 pipe.AddShader(&vs);
1819 pipe.AddShader(&fs);
1820
1821 VkCommandBufferObj dummyCmd(m_device);
1822 VkDescriptorSetObj descriptorSet(m_device);
1823 descriptorSet.AppendDummy();
1824 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1825
1826 m_errorMonitor->ClearState();
1827 pipe.CreateVKPipeline(descriptorSet);
1828
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001829 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001830
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001831 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001832 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
1833 FAIL() << "Incorrect warning: " << msgString;
1834 }
1835}
Chris Forbes5af3bf22015-05-25 11:13:08 +12001836
Chris Forbes3c10b852015-05-25 11:13:13 +12001837TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
1838{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001839 VkFlags msgFlags;
Chris Forbes3c10b852015-05-25 11:13:13 +12001840 std::string msgString;
1841 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001842 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12001843
1844 char const *vsSource =
1845 "#version 140\n"
1846 "#extension GL_ARB_separate_shader_objects: require\n"
1847 "#extension GL_ARB_shading_language_420pack: require\n"
1848 "\n"
1849 "void main(){\n"
1850 " gl_Position = vec4(1);\n"
1851 "}\n";
1852 char const *fsSource =
1853 "#version 140\n"
1854 "#extension GL_ARB_separate_shader_objects: require\n"
1855 "#extension GL_ARB_shading_language_420pack: require\n"
1856 "\n"
1857 "layout(location=0) in float x;\n"
1858 "layout(location=0) out vec4 color;\n"
1859 "void main(){\n"
1860 " color = vec4(x);\n"
1861 "}\n";
1862
1863 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1864 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1865
1866 VkPipelineObj pipe(m_device);
1867 pipe.AddShader(&vs);
1868 pipe.AddShader(&fs);
1869
1870 VkCommandBufferObj dummyCmd(m_device);
1871 VkDescriptorSetObj descriptorSet(m_device);
1872 descriptorSet.AppendDummy();
1873 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1874
1875 m_errorMonitor->ClearState();
1876 pipe.CreateVKPipeline(descriptorSet);
1877
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001878 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes3c10b852015-05-25 11:13:13 +12001879
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001880 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes3c10b852015-05-25 11:13:13 +12001881 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
1882 FAIL() << "Incorrect error: " << msgString;
1883 }
1884}
1885
Chris Forbescc281692015-05-25 11:13:17 +12001886TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
1887{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001888 VkFlags msgFlags;
Chris Forbescc281692015-05-25 11:13:17 +12001889 std::string msgString;
1890 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001891 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12001892
1893 char const *vsSource =
1894 "#version 140\n"
1895 "#extension GL_ARB_separate_shader_objects: require\n"
1896 "#extension GL_ARB_shading_language_420pack: require\n"
1897 "\n"
1898 "layout(location=0) out int x;\n"
1899 "void main(){\n"
1900 " x = 0;\n"
1901 " gl_Position = vec4(1);\n"
1902 "}\n";
1903 char const *fsSource =
1904 "#version 140\n"
1905 "#extension GL_ARB_separate_shader_objects: require\n"
1906 "#extension GL_ARB_shading_language_420pack: require\n"
1907 "\n"
1908 "layout(location=0) in float x;\n" /* VS writes int */
1909 "layout(location=0) out vec4 color;\n"
1910 "void main(){\n"
1911 " color = vec4(x);\n"
1912 "}\n";
1913
1914 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1915 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1916
1917 VkPipelineObj pipe(m_device);
1918 pipe.AddShader(&vs);
1919 pipe.AddShader(&fs);
1920
1921 VkCommandBufferObj dummyCmd(m_device);
1922 VkDescriptorSetObj descriptorSet(m_device);
1923 descriptorSet.AppendDummy();
1924 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1925
1926 m_errorMonitor->ClearState();
1927 pipe.CreateVKPipeline(descriptorSet);
1928
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001929 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbescc281692015-05-25 11:13:17 +12001930
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001931 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbescc281692015-05-25 11:13:17 +12001932 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
1933 FAIL() << "Incorrect error: " << msgString;
1934 }
1935}
1936
Chris Forbes8291c052015-05-25 11:13:28 +12001937TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
1938{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001939 VkFlags msgFlags;
Chris Forbes8291c052015-05-25 11:13:28 +12001940 std::string msgString;
1941 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001942 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12001943
1944 VkVertexInputBindingDescription input_binding;
1945 memset(&input_binding, 0, sizeof(input_binding));
1946
1947 VkVertexInputAttributeDescription input_attrib;
1948 memset(&input_attrib, 0, sizeof(input_attrib));
1949 input_attrib.format = VK_FORMAT_R32_SFLOAT;
1950
1951 char const *vsSource =
1952 "#version 140\n"
1953 "#extension GL_ARB_separate_shader_objects: require\n"
1954 "#extension GL_ARB_shading_language_420pack: require\n"
1955 "\n"
1956 "void main(){\n"
1957 " gl_Position = vec4(1);\n"
1958 "}\n";
1959 char const *fsSource =
1960 "#version 140\n"
1961 "#extension GL_ARB_separate_shader_objects: require\n"
1962 "#extension GL_ARB_shading_language_420pack: require\n"
1963 "\n"
1964 "layout(location=0) out vec4 color;\n"
1965 "void main(){\n"
1966 " color = vec4(1);\n"
1967 "}\n";
1968
1969 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1970 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1971
1972 VkPipelineObj pipe(m_device);
1973 pipe.AddShader(&vs);
1974 pipe.AddShader(&fs);
1975
1976 pipe.AddVertexInputBindings(&input_binding, 1);
1977 pipe.AddVertexInputAttribs(&input_attrib, 1);
1978
1979 VkCommandBufferObj dummyCmd(m_device);
1980 VkDescriptorSetObj descriptorSet(m_device);
1981 descriptorSet.AppendDummy();
1982 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1983
1984 m_errorMonitor->ClearState();
1985 pipe.CreateVKPipeline(descriptorSet);
1986
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001987 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes8291c052015-05-25 11:13:28 +12001988
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001989 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes8291c052015-05-25 11:13:28 +12001990 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
1991 FAIL() << "Incorrect warning: " << msgString;
1992 }
1993}
1994
Chris Forbes37367e62015-05-25 11:13:29 +12001995TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
1996{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001997 VkFlags msgFlags;
Chris Forbes37367e62015-05-25 11:13:29 +12001998 std::string msgString;
1999 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002000 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12002001
2002 char const *vsSource =
2003 "#version 140\n"
2004 "#extension GL_ARB_separate_shader_objects: require\n"
2005 "#extension GL_ARB_shading_language_420pack: require\n"
2006 "\n"
2007 "layout(location=0) in vec4 x;\n" /* not provided */
2008 "void main(){\n"
2009 " gl_Position = x;\n"
2010 "}\n";
2011 char const *fsSource =
2012 "#version 140\n"
2013 "#extension GL_ARB_separate_shader_objects: require\n"
2014 "#extension GL_ARB_shading_language_420pack: require\n"
2015 "\n"
2016 "layout(location=0) out vec4 color;\n"
2017 "void main(){\n"
2018 " color = vec4(1);\n"
2019 "}\n";
2020
2021 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2022 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2023
2024 VkPipelineObj pipe(m_device);
2025 pipe.AddShader(&vs);
2026 pipe.AddShader(&fs);
2027
2028 VkCommandBufferObj dummyCmd(m_device);
2029 VkDescriptorSetObj descriptorSet(m_device);
2030 descriptorSet.AppendDummy();
2031 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2032
2033 m_errorMonitor->ClearState();
2034 pipe.CreateVKPipeline(descriptorSet);
2035
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002036 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes37367e62015-05-25 11:13:29 +12002037
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002038 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes37367e62015-05-25 11:13:29 +12002039 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2040 FAIL() << "Incorrect warning: " << msgString;
2041 }
2042}
2043
Chris Forbesa4b02322015-05-25 11:13:31 +12002044TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2045{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002046 VkFlags msgFlags;
Chris Forbesa4b02322015-05-25 11:13:31 +12002047 std::string msgString;
2048 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002049 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002050
2051 VkVertexInputBindingDescription input_binding;
2052 memset(&input_binding, 0, sizeof(input_binding));
2053
2054 VkVertexInputAttributeDescription input_attrib;
2055 memset(&input_attrib, 0, sizeof(input_attrib));
2056 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2057
2058 char const *vsSource =
2059 "#version 140\n"
2060 "#extension GL_ARB_separate_shader_objects: require\n"
2061 "#extension GL_ARB_shading_language_420pack: require\n"
2062 "\n"
2063 "layout(location=0) in int x;\n" /* attrib provided float */
2064 "void main(){\n"
2065 " gl_Position = vec4(x);\n"
2066 "}\n";
2067 char const *fsSource =
2068 "#version 140\n"
2069 "#extension GL_ARB_separate_shader_objects: require\n"
2070 "#extension GL_ARB_shading_language_420pack: require\n"
2071 "\n"
2072 "layout(location=0) out vec4 color;\n"
2073 "void main(){\n"
2074 " color = vec4(1);\n"
2075 "}\n";
2076
2077 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2078 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2079
2080 VkPipelineObj pipe(m_device);
2081 pipe.AddShader(&vs);
2082 pipe.AddShader(&fs);
2083
2084 pipe.AddVertexInputBindings(&input_binding, 1);
2085 pipe.AddVertexInputAttribs(&input_attrib, 1);
2086
2087 VkCommandBufferObj dummyCmd(m_device);
2088 VkDescriptorSetObj descriptorSet(m_device);
2089 descriptorSet.AppendDummy();
2090 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2091
2092 m_errorMonitor->ClearState();
2093 pipe.CreateVKPipeline(descriptorSet);
2094
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002095 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa4b02322015-05-25 11:13:31 +12002096
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002097 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa4b02322015-05-25 11:13:31 +12002098 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2099 FAIL() << "Incorrect error: " << msgString;
2100 }
2101}
2102
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002103TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2104{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002105 VkFlags msgFlags;
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002106 std::string msgString;
2107 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002108 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002109
2110 /* Two binding descriptions for binding 0 */
2111 VkVertexInputBindingDescription input_bindings[2];
2112 memset(input_bindings, 0, sizeof(input_bindings));
2113
2114 VkVertexInputAttributeDescription input_attrib;
2115 memset(&input_attrib, 0, sizeof(input_attrib));
2116 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2117
2118 char const *vsSource =
2119 "#version 140\n"
2120 "#extension GL_ARB_separate_shader_objects: require\n"
2121 "#extension GL_ARB_shading_language_420pack: require\n"
2122 "\n"
2123 "layout(location=0) in float x;\n" /* attrib provided float */
2124 "void main(){\n"
2125 " gl_Position = vec4(x);\n"
2126 "}\n";
2127 char const *fsSource =
2128 "#version 140\n"
2129 "#extension GL_ARB_separate_shader_objects: require\n"
2130 "#extension GL_ARB_shading_language_420pack: require\n"
2131 "\n"
2132 "layout(location=0) out vec4 color;\n"
2133 "void main(){\n"
2134 " color = vec4(1);\n"
2135 "}\n";
2136
2137 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2138 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2139
2140 VkPipelineObj pipe(m_device);
2141 pipe.AddShader(&vs);
2142 pipe.AddShader(&fs);
2143
2144 pipe.AddVertexInputBindings(input_bindings, 2);
2145 pipe.AddVertexInputAttribs(&input_attrib, 1);
2146
2147 VkCommandBufferObj dummyCmd(m_device);
2148 VkDescriptorSetObj descriptorSet(m_device);
2149 descriptorSet.AppendDummy();
2150 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2151
2152 m_errorMonitor->ClearState();
2153 pipe.CreateVKPipeline(descriptorSet);
2154
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002155 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002156
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002157 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002158 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2159 FAIL() << "Incorrect error: " << msgString;
2160 }
2161}
Chris Forbes4c948702015-05-25 11:13:32 +12002162
Chris Forbesc12ef122015-05-25 11:13:40 +12002163/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2164 * rejects it. */
2165
2166TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2167{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002168 VkFlags msgFlags;
Chris Forbesc12ef122015-05-25 11:13:40 +12002169 std::string msgString;
2170 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002171 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002172
2173 char const *vsSource =
2174 "#version 140\n"
2175 "#extension GL_ARB_separate_shader_objects: require\n"
2176 "#extension GL_ARB_shading_language_420pack: require\n"
2177 "\n"
2178 "void main(){\n"
2179 " gl_Position = vec4(1);\n"
2180 "}\n";
2181 char const *fsSource =
2182 "#version 140\n"
2183 "#extension GL_ARB_separate_shader_objects: require\n"
2184 "#extension GL_ARB_shading_language_420pack: require\n"
2185 "\n"
2186 "void main(){\n"
2187 "}\n";
2188
2189 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2190 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2191
2192 VkPipelineObj pipe(m_device);
2193 pipe.AddShader(&vs);
2194 pipe.AddShader(&fs);
2195
2196 /* implicit CB 0 set up by the test framework, not written */
2197
2198 VkCommandBufferObj dummyCmd(m_device);
2199 VkDescriptorSetObj descriptorSet(m_device);
2200 descriptorSet.AppendDummy();
2201 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2202
2203 m_errorMonitor->ClearState();
2204 pipe.CreateVKPipeline(descriptorSet);
2205
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002206 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc12ef122015-05-25 11:13:40 +12002207
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002208 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc12ef122015-05-25 11:13:40 +12002209 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2210 FAIL() << "Incorrect error: " << msgString;
2211 }
2212}
2213
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002214TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2215{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002216 VkFlags msgFlags;
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002217 std::string msgString;
2218 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002219 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002220
2221 char const *vsSource =
2222 "#version 140\n"
2223 "#extension GL_ARB_separate_shader_objects: require\n"
2224 "#extension GL_ARB_shading_language_420pack: require\n"
2225 "\n"
2226 "void main(){\n"
2227 " gl_Position = vec4(1);\n"
2228 "}\n";
2229 char const *fsSource =
2230 "#version 140\n"
2231 "#extension GL_ARB_separate_shader_objects: require\n"
2232 "#extension GL_ARB_shading_language_420pack: require\n"
2233 "\n"
2234 "layout(location=0) out vec4 x;\n"
2235 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2236 "void main(){\n"
2237 " x = vec4(1);\n"
2238 " y = vec4(1);\n"
2239 "}\n";
2240
2241 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2242 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2243
2244 VkPipelineObj pipe(m_device);
2245 pipe.AddShader(&vs);
2246 pipe.AddShader(&fs);
2247
2248 /* implicit CB 0 set up by the test framework */
2249 /* FS writes CB 1, but we don't configure it */
2250
2251 VkCommandBufferObj dummyCmd(m_device);
2252 VkDescriptorSetObj descriptorSet(m_device);
2253 descriptorSet.AppendDummy();
2254 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2255
2256 m_errorMonitor->ClearState();
2257 pipe.CreateVKPipeline(descriptorSet);
2258
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002259 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002260
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002261 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002262 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2263 FAIL() << "Incorrect warning: " << msgString;
2264 }
2265}
2266
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002267TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2268{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002269 VkFlags msgFlags;
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002270 std::string msgString;
2271 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002272 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002273
2274 char const *vsSource =
2275 "#version 140\n"
2276 "#extension GL_ARB_separate_shader_objects: require\n"
2277 "#extension GL_ARB_shading_language_420pack: require\n"
2278 "\n"
2279 "void main(){\n"
2280 " gl_Position = vec4(1);\n"
2281 "}\n";
2282 char const *fsSource =
2283 "#version 140\n"
2284 "#extension GL_ARB_separate_shader_objects: require\n"
2285 "#extension GL_ARB_shading_language_420pack: require\n"
2286 "\n"
2287 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2288 "void main(){\n"
2289 " x = ivec4(1);\n"
2290 "}\n";
2291
2292 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2293 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2294
2295 VkPipelineObj pipe(m_device);
2296 pipe.AddShader(&vs);
2297 pipe.AddShader(&fs);
2298
2299 /* implicit CB 0 set up by test framework, is UNORM. */
2300
2301 VkCommandBufferObj dummyCmd(m_device);
2302 VkDescriptorSetObj descriptorSet(m_device);
2303 descriptorSet.AppendDummy();
2304 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2305
2306 m_errorMonitor->ClearState();
2307 pipe.CreateVKPipeline(descriptorSet);
2308
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002309 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002310
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002311 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002312 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2313 FAIL() << "Incorrect error: " << msgString;
2314 }
2315}
Chris Forbesc2050732015-06-05 14:43:36 +12002316
2317TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2318{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002319 VkFlags msgFlags;
Chris Forbesc2050732015-06-05 14:43:36 +12002320 std::string msgString;
2321 ASSERT_NO_FATAL_FAILURE(InitState());
2322 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002323 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002324
2325 char const *vsSource =
2326 "#version 140\n"
2327 "#extension GL_ARB_separate_shader_objects: require\n"
2328 "#extension GL_ARB_shading_language_420pack: require\n"
2329 "\n"
2330 "void main(){\n"
2331 " gl_Position = vec4(1);\n"
2332 "}\n";
2333 char const *fsSource =
2334 "#version 140\n"
2335 "#extension GL_ARB_separate_shader_objects: require\n"
2336 "#extension GL_ARB_shading_language_420pack: require\n"
2337 "\n"
2338 "layout(location=0) out vec4 x;\n"
2339 "void main(){\n"
2340 " x = vec4(1);\n"
2341 "}\n";
2342
2343 m_errorMonitor->ClearState();
2344
2345 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2346 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2347
2348
2349 VkPipelineObj pipe(m_device);
2350 pipe.AddShader(&vs);
2351 pipe.AddShader(&fs);
2352
2353 /* implicit CB 0 set up by test framework, is UNORM. */
2354
2355 VkCommandBufferObj dummyCmd(m_device);
2356 VkDescriptorSetObj descriptorSet(m_device);
2357 descriptorSet.AppendDummy();
2358 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2359
2360 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2361 /* pipeline creation should have succeeded */
2362 ASSERT_EQ(VK_SUCCESS, res);
2363
2364 /* should have emitted a warning: the shader is not SPIRV, so we're
2365 * not going to be able to analyze it */
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002366 msgFlags = m_errorMonitor->GetState(&msgString);
2367 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesc2050732015-06-05 14:43:36 +12002368 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2369 FAIL() << "Incorrect warning: " << msgString;
2370 }
2371}
Chris Forbes01c9db72015-06-04 09:25:25 +12002372#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002373
Tony Barbour30486ea2015-04-07 13:44:53 -06002374int main(int argc, char **argv) {
2375 int result;
2376
2377 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002378 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002379
2380 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2381
2382 result = RUN_ALL_TESTS();
2383
Tony Barbour01999182015-04-09 12:58:51 -06002384 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002385 return result;
2386}